我有一个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的值。即使他们拒绝了改变,它也会像他们所选择的一样保持不变。出于某种原因,似乎在设置属性之后才设置组合框的项目。此时它会显示用户选择的内容,而不是代码隐藏中存在的正确值。
答案 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);
}
}