WPF ComboBox - 更改绑定字段的setter中的选择 - ComboBox选择未更新

时间:2012-10-04 19:26:20

标签: c# wpf data-binding combobox

我有一个ComboBox的SelectedItem属性绑定到对象的字段。它使用TwoWay绑定,在大多数情况下工作正常;当它加载时,下拉列表的选择是从字段的getter设置的,手动更改选择会调用字段的setter。

但是,有时我想显示一个确认对话框。如果用户单击“否”,我希望值保持不变。这是我的代码:

public A Afield
{
    get { return _afield; }
    set
    {
        SetA(value);
    }
}
public void SetA(LocationConfiguration value, bool prompt = true)
{
    if (/*selection would cause irreversible changes*/)
    {
        if (prompt)
        {
            MessageBoxResult result = Microsoft.Windows.Controls.MessageBox.Show(
                    "bla bla bla",
                    "bla",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Warning);
            if (result != MessageBoxResult.Yes)
                return;
        }
        PerformIrreversibleChanges()
    }
    _afield = value;
    NotifyPropertyChanged("Afield");
}

代码隐藏中的所有内容都能完美运行。如果用户接受,则进行更改。如果用户按“否”,则不修改_afield。绑定到此属性的其他控件显示正确的值。

但是,ComboBox显示不会恢复为_afield的值。即使他们拒绝了改变,它也会像他们所选择的一样保持不变。出于某种原因,似乎在设置属性之后才设置组合框的项目。此时它会显示用户选择的内容,而不是代码隐藏中存在的正确值。

4 个答案:

答案 0 :(得分:0)

您需要将其设置回来,因为双向绑定会在选择更改后立即更新属性,因此如果用户取消更改,您需要将其重置为prev值。您可以查看事件args的RemovedItems属性以获取先前的值。

答案 1 :(得分:0)

我设法修复它,但解决方案并不漂亮。除了绑定之外,我现在有一个SelectionChanged事件的处理程序,它将选择更改回应该是什么。这是代码:

private void cbox_Abox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    foreach (ComboBoxItem cbi in cbox_Abox.Items)
        if ((string)cbi.Content == BoundObject.Afield.ToString())
            cbox_Abox.SelectedItem = cbi;
}

现在,每当我手动选择ComboBox值时,它会通过绑定将值写入对象(就像之前一样),然后使用此处理程序将值从对象复制回ComboBox。 / p>

出于某种原因,在这里使用PropertyChanged事件不会更新组合框,这就是我必须明确调用ComboBox.SelectedIndex的原因。

答案 2 :(得分:0)

让SetA返回一个布尔值

set
{
     if (value == _afield) return;         
     if (SetA(value)) _afield = value;
     NotifyPropertyChanged("Afield");
}

答案 3 :(得分:0)

或者,如果用户按下“否​​”,您可以保存以前的值并将其保留为后备值

 private A previousAfield;
 public A Afield
 {
    get { return _afield; }
    set
    {
       previousAfield = _afield;
       SetA(value);
    }
 }