Posted 13 years ago
by Michael Davis
Version: 11.1.0543
Platform: .NET 4.0
Environment: Windows 7 (64-bit)
I have a situation where I have an Int32EditBox bound to a property on my view model and, under some circumstances, I need to display a confirmation prompt whenever the user changes the value.
I started to do this by handling the ValueChanging event to display a message box and setting the eventArgs.Cancel property to true if the user chose not to confirm the change. As expected, the value in the UI returns to the old value. However, the binding source property is always updated to the new value regardless of the cancellation.
I've come up with a workaround that seems to be working in my case (specifically, I'm listening for the SourceUpdated event instead and reverting the change from there if necessary), but I think this behavior is, if not wrong, then at least very unintuitive. Am I missing anything here about how this is supposed to work?
Here is some sample code that demonstrates the problem. If you enter an odd number in the Int32EditBox, the event handler will cancel the change, but it still propagates to the model and updates the TextBox below.
I started to do this by handling the ValueChanging event to display a message box and setting the eventArgs.Cancel property to true if the user chose not to confirm the change. As expected, the value in the UI returns to the old value. However, the binding source property is always updated to the new value regardless of the cancellation.
I've come up with a workaround that seems to be working in my case (specifically, I'm listening for the SourceUpdated event instead and reverting the change from there if necessary), but I think this behavior is, if not wrong, then at least very unintuitive. Am I missing anything here about how this is supposed to work?
Here is some sample code that demonstrates the problem. If you enter an odd number in the Int32EditBox, the event handler will cancel the change, but it still propagates to the model and updates the TextBox below.
using System.ComponentModel;
using System.Windows;
using ActiproSoftware.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Int32EditBox_ValueChanging(object sender, PropertyChangingRoutedEventArgs<int?> e)
{
e.Cancel = (e.NewValue % 2) == 1; // Cancel change if the new value is an odd number
}
}
public class Model : INotifyPropertyChanged
{
private int _value = 42;
public int Value
{
get { return _value; }
set
{
_value = value;
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfApplication1="clr-namespace:WpfApplication1"
xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<WpfApplication1:Model />
</Window.DataContext>
<StackPanel>
<editors:Int32EditBox Name="_editor"
Value="{Binding Value, Mode=TwoWay}"
ValueChanging="Int32EditBox_ValueChanging" />
<TextBox Name="_textBox"
Text="{Binding Value, Mode=TwoWay}" />
</StackPanel>
</Window>