编辑对话框,绑定和确定/取消在WPF
我怎样才能有一个对话框编辑一个类的属性与绑定,并在对话框中有确定 - 取消?编辑对话框,绑定和确定/取消在WPF
我最初的想法是这样的:
public partial class EditServerDialog : Window {
private NewsServer _newsServer;
public EditServerDialog(NewsServer newsServer) {
InitializeComponent();
this.DataContext = (_newsServer = newsServer).Clone();
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
switch (((Button)e.OriginalSource).Content.ToString()) {
case "OK":
_newsServer = (NewsServer)this.DataContext;
this.Close();
break;
case "Cancel":
this.Close();
break;
}
}
}
当开关的情况下“OK”,在DataContext包含正确的信息,但最初传递NewsServer情况下不会改变。
您的NewsServer
对象的原始实例未更改,因为您尚未实际修改它。您的构造函数被调用后,您有以下三个NewsServer
引用:
newsServer = original instance
_newsServer = original instance
DataContext = clone of original instance
的OK按钮被点击后,引用将如下:
newsServer = original instance
_newsServer = clone of original instance (possibly modified)
DataContext = clone of original instance (possibly modified)
记住,对象是引用类型,在你的作业到_newsServer
您只更新其引用,而不是对象本身的值。
为了允许更新NewsServer
对象本身,有两个选项可以想到,其他选项可能存在,第一个可能是最简单的。
- 贯彻执行新的分配到
_newsServer
领域,而不是调用它的更新方法,并传入DataContext
参考价值的NewsServer
对象上void Update(NewsServer source)
方法则不用。 - 公开
_newsServer
值与公共/内部属性。您可以通过多种机制来使用它:显式响应在属性值更改时引发的事件;绑定到属性(例如,使其成为依赖属性或实现INotifyPropertyChanged
);或者只是期望调用者在ShowDialog()
方法返回的值为true
的情况下以及何时返回该值。
请注意,如果您在调用方上推回一点逻辑,您的对话类可以更简单。特别是,一种方法是仅对维护通过属性暴露给调用者的克隆对象(例如,完全去掉_newsServer
字段并仅使用DataContext
)。这个对象像以前一样被绑定到对话框的元素上。调用者只需从ShowDialog()
方法的true
结果中检索此实例的参考。
例如:
NewsServer newsServer = ...;
EditServerDialog editServerDialog = new EditServerDialog(newsServer);
if (editServerDialog.ShowDialog() == true)
{
newsServer = editServerDialog.DataContext;
}
克隆的目的将简单地由呼叫者被忽略,如果对话被取消,并且因此ShowDialog()
方法返回false
。您可以重新使用DataContext
属性(如上所示),或者您可以创建一个仅返回DataContext
属性值(即,使代码对对话类的公共接口更清晰一些)的不同属性(例如名为NewsServer
)。
我应该怎么做,仍然可以取消和/或申请? – ErikTJ 2010-04-05 07:44:32
老问题,但我会回答它为未来的读者...
您必须在您的绑定上设置UpdateSourceTrigger="Explicit"
,以便它们不会更新实际源,直到用户单击确定。然后在你的OK按钮处理程序,你可以写:
BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty);
if (be!=null) be.UpdateSource();
此外,如果要重置绑定到初始状态使用
BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty);
if (be!=null) be.UpdateTarget();
如果你的对话框是复杂的,你可能要递归走所有的控件。
这是一个老问题,但我最近遇到了这个问题,发现有更好的方法来处理它与.NET 4.5。
首先,标志着您的绑定UpdateSourceTrigger为明确:
<CheckBox IsChecked="{Binding MyProperty, UpdateSourceTrigger=Explicit}"/>
然后,在你确定按钮单击事件处理程序使用此:
foreach (var be in BindingOperations.GetSourceUpdatingBindings(this))
{
be.UpdateSource();
}
GetSourceUpdatingBindings是在.NET 4.5的新方法。
取消按钮不需要执行任何操作,因为绑定已标记为Explicit,并且只有在调用UpdateSource时才会“提交”。
如果您显示设置的绑定,它可能会有所帮助。 – 2010-04-01 10:58:11
绑定示例:{Binding NeedAuthentication,UpdateSourceTrigger = LostFocus,Mode = TwoWay}。 绑定是正确的,因为this.DataContext包含正确的数据。 – ErikTJ 2010-04-01 11:10:20