我想开发用于编辑利用多态的对象的对话框。目前我正在使用这种模式:
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;
我相信有更好的设计模式使用数据绑定等。所以基本上我有两个问题。
答案 0 :(得分:1)
我相信您正在寻找的是DataBinding和DataTemplating的组合。 DataTemplating允许您为不同的业务对象定义不同的可视元素(在本例中为MyBooleanSettings
和MyStringSettings
。DataBinding将允许可视元素更新并更新业务对象中的数据。
示例(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>
然后在后面的代码中定义:
public MyObject ObjectToEdit { get; set; }
最后更新您的对象:
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");
}
}
}
}
但是,如果您确实需要控制视图和对象同步的时间,则应使用相应绑定上的UpdateSourceTrigger
属性。
如果你想要一些额外的阅读,我建议:http://msdn.microsoft.com/en-us/library/ms752347.aspx
答案 1 :(得分:0)
DataBinding很简单。您可以创建MyObject的实例并将其分配给Form的DataContext属性。
this.DataContext=MyObject;
定义单个元素的绑定。
<TextBox Name="txtTitle" Text="{Binding Path=Title,Mode=TwoWay }" />
当您在UI中进行更改时,以两种方式设置模式将影响对象。一种方法将显示值。
答案 2 :(得分:0)
创建MyObject实例的副本。在Result属性get方法中,如果用户点击取消返回副本(返回未更改的副本),或者如果用户点击OK,则返回已更改的MyObject实例。
问题是什么?