2010-04-01 42 views
5

我怎样才能有一个对话框编辑一个类的属性与绑定,并在对话框中有确定 - 取消?编辑对话框,绑定和确定/取消在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情况下不会改变。

+0

如果您显示设置的绑定,它可能会有所帮助。 – 2010-04-01 10:58:11

+0

绑定示例:{Binding NeedAuthentication,UpdateSourceTrigger = LostFocus,Mode = TwoWay}。 绑定是正确的,因为this.DataContext包含正确的数据。 – ErikTJ 2010-04-01 11:10:20

回答

1

您的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)。

+0

我应该怎么做,仍然可以取消和/或申请? – ErikTJ 2010-04-05 07:44:32

3

老问题,但我会回答它为未来的读者...

您必须在您的绑定上设置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(); 

如果你的对话框是复杂的,你可能要递归走所有的控件。

0

这是一个老问题,但我最近遇到了这个问题,发现有更好的方法来处理它与.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时才会“提交”。

相关问题