Which design template should be used to create such dialogs?

I want to develop a dialog for editing objects that use polymorphism. I am currently using this template:

MyObject.cs:

using System; namespace WpfApplication3 { public class MyObject { public string Title { get; set; } public MySettings Settings { get; set; } } public abstract class MySettings { public abstract string GetSettingsString(); } public class MyBoolSettings : MySettings { public bool BoolSetting { get; set; } public override string GetSettingsString() { return "BoolSetting = " + BoolSetting; } } public class MyStringSettings : MySettings { public string StringSetting { get; set; } public override string GetSettingsString() { return "StringSetting = " + StringSetting; } } } 

MainWindow.xaml:

 <Window x:Class="WpfApplication3.EditMyObjectDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="EditMyObjectDialog" Height="350" Width="350"> <StackPanel Margin="20"> <TextBlock Text="Title" /> <TextBox Name="txtTitle" /> <RadioButton Name="rdBoolSettings" Content="BoolSettings" IsChecked="True" Margin="0, 20, 0, 0" /> <CheckBox Name="chBool" Content="True" Margin="20, 0, 0, 20" /> <RadioButton Name="rdStringSettings" Content="StringSettings" /> <TextBox Name="txtString" Margin="20, 0, 0, 20"/> <Button Content="OK" Click="OK_click" /> <Button Content="Cancel" Click="Cancel_click" Margin="0, 10" /> </StackPanel> </Window> 

MainWindow.xaml.cs:

 using System.Windows; namespace WpfApplication3 { public partial class EditMyObjectDialog : Window { public MyObject Result { get; set; } public EditMyObjectDialog(MyObject objectToEdit) { InitializeComponent(); txtTitle.Text = objectToEdit.Title; if (objectToEdit.Settings is MyBoolSettings) { rdBoolSettings.IsChecked = true; chBool.IsChecked = (objectToEdit.Settings as MyBoolSettings).BoolSetting; } if (objectToEdit.Settings is MyStringSettings) { rdBoolSettings.IsChecked = true; txtString.Text = (objectToEdit.Settings as MyStringSettings).StringSetting; } } private void OK_click(object sender, RoutedEventArgs e) { Result = new MyObject() { Title = txtTitle.Text }; if (rdBoolSettings.IsChecked == true) Result.Settings = new MyBoolSettings() { BoolSetting = chBool.IsChecked == true }; if (rdStringSettings.IsChecked == true) Result.Settings = new MyStringSettings() { StringSetting = txtString.Text }; DialogResult = true; } private void Cancel_click(object sender, RoutedEventArgs e) { DialogResult = false; } } } 

ExternalCode:

 var f = new EditMyObjectDialog(myObject); if (f.ShowDialog() == true) myObject = f.Result; 

I believe that there is a much better design template that uses data binding, etc. So basically I have two questions.

  • How to make data binding not to change the object until the user clicks "OK"?
  • How to properly handle the "Settings" property? What to do when user type switch settings?
0
source share
3 answers

I believe you are looking for a combination of DataBinding and DataTemplating. DataTemplating allows you to define different visual elements for different business objects (in this case, MyBooleanSettings and MyStringSettings ). DataBinding will allow visual elements to update and update my data in business objects.

Example (xaml):

 <Window DataContext={Binding RelativeSource={RelativeSource Self}}"> <Window.Resources> <DataTemplate DataType={x:Type local:MyObject}"> <TextBlock Text={Binding Title}" /> <ContentPresenter Content="{Binding Settings}" /> </DataTemplate> <DataTemplate DataType={x:Type local:MyObject}"> <TextBox Text={Binding </DataTemplate> <DataTemplate DataType={x:Type local:MyBoolSettings}> <CheckBox IsChecked="{Binding BoolSetting}" /> </DataTemplate> <DataTemplate DataType={x:Type local:MyStringSettings}> <TextBox Text="{Binding StringSetting}" /> </DataTemplate> </Window.Resources> <ContentPresenter Content="{Binding ObjectToEdit}" /> </Window> 

Then in the code behind define:

 public MyObject ObjectToEdit { get; set; } 

Finally, update your objects:

 public class MySettings : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(sting s) { if(PropertyChanged != null) { PropertyChanged(s); } } } public class BoolSettings : MySettings { bool _value; bool BoolSetting { get { return _value; } set { if(_value != value) { _value = value; OnPropertyChanged("BoolSetting"); } } } } 

If you really need to control when synchronizing the view and the object, you should use the UpdateSourceTrigger property for the corresponding bindings.

If you require additional reading, I recommend: http://msdn.microsoft.com/en-us/library/ms752347.aspx

+1
source

DataBinding is easy. You can create an instance of MyObject and assign it to the form's DataContext property.

 this.DataContext=MyObject; 

And define a binding for individual elements.

  <TextBox Name="txtTitle" Text="{Binding Path=Title,Mode=TwoWay }" /> 

Setup mode as two ways will affect the object when changing the user interface. One way will display the values.

0
source
  • How to make data binding not to change the object until the user clicks "OK"?

Create a copy of the MyObject instance. In the get method of the Result property, return the copy if the user clicks cancel (return the unmodified copy), or if the user clicks OK, return the modified instance of MyObject.

  • How to properly handle the "Settings" property? What to do when the user switches the type of installation?

What is the problem?

0
source

Source: https://habr.com/ru/post/1483148/


All Articles