Для достижения этого под MVVM ....
1] Имейте прикрепленное поведение, которое обрабатывает событие SelectionChanged
ComboBox. Это событие вызывается с некоторыми аргументами события, имеющими флаг Handled
. Но установка его в true бесполезна для SelectedValue
привязки. Привязка обновляет источник независимо от того, было ли обработано событие.
2] Следовательно, мы настраиваем привязку ComboBox.SelectedValue
на TwoWay
и Explicit
.
3] Только когда ваш чек удовлетворен и в окне сообщения указано, что Yes
- это когда мы выполняем BindingExpression.UpdateSource()
. В противном случае мы просто вызываем BindingExpression.UpdateTarget()
, чтобы вернуться к старому выбору.
В моем примере ниже у меня есть список KeyValuePair<int, int>
, связанный с контекстом данных окна. ComboBox.SelectedValue
связан с простым записываемым свойством MyKey
Window
.
XAML ...
<ComboBox ItemsSource="{Binding}"
DisplayMemberPath="Value"
SelectedValuePath="Key"
SelectedValue="{Binding MyKey,
ElementName=MyDGSampleWindow,
Mode=TwoWay,
UpdateSourceTrigger=Explicit}"
local:MyAttachedBehavior.ConfirmationValueBinding="True">
</ComboBox>
Где MyDGSampleWindow
- это x: Имя Window
.
Код позади ...
public partial class Window1 : Window
{
private List<KeyValuePair<int, int>> list1;
public int MyKey
{
get; set;
}
public Window1()
{
InitializeComponent();
list1 = new List<KeyValuePair<int, int>>();
var random = new Random();
for (int i = 0; i < 50; i++)
{
list1.Add(new KeyValuePair<int, int>(i, random.Next(300)));
}
this.DataContext = list1;
}
}
И прикрепленное поведение
public static class MyAttachedBehavior
{
public static readonly DependencyProperty
ConfirmationValueBindingProperty
= DependencyProperty.RegisterAttached(
"ConfirmationValueBinding",
typeof(bool),
typeof(MyAttachedBehavior),
new PropertyMetadata(
false,
OnConfirmationValueBindingChanged));
public static bool GetConfirmationValueBinding
(DependencyObject depObj)
{
return (bool) depObj.GetValue(
ConfirmationValueBindingProperty);
}
public static void SetConfirmationValueBinding
(DependencyObject depObj,
bool value)
{
depObj.SetValue(
ConfirmationValueBindingProperty,
value);
}
private static void OnConfirmationValueBindingChanged
(DependencyObject depObj,
DependencyPropertyChangedEventArgs e)
{
var comboBox = depObj as ComboBox;
if (comboBox != null && (bool)e.NewValue)
{
comboBox.Tag = false;
comboBox.SelectionChanged -= ComboBox_SelectionChanged;
comboBox.SelectionChanged += ComboBox_SelectionChanged;
}
}
private static void ComboBox_SelectionChanged(
object sender, SelectionChangedEventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox != null && !(bool)comboBox.Tag)
{
var bndExp
= comboBox.GetBindingExpression(
Selector.SelectedValueProperty);
var currentItem
= (KeyValuePair<int, int>) comboBox.SelectedItem;
if (currentItem.Key >= 1 && currentItem.Key <= 4
&& bndExp != null)
{
var dr
= MessageBox.Show(
"Want to select a Key of between 1 and 4?",
"Please Confirm.",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (dr == MessageBoxResult.Yes)
{
bndExp.UpdateSource();
}
else
{
comboBox.Tag = true;
bndExp.UpdateTarget();
comboBox.Tag = false;
}
}
}
}
}
В поведении я использую свойство ComboBox.Tag
, чтобы временно сохранить флаг, который пропускает перепроверку, когда мы возвращаемся к старому выбранному значению.
Дайте мне знать, если это поможет.