I am integrating property change detection in an application by way of MultiBinding
and IMultiValueConverter
. So when a user makes changes to a \'DataG
I wouldn't rely on OneTime binding mode and tricks with clearing binding to track changes in data. Implement something like Memento pattern instead.
Add this code which stores state in Item class:
private Dictionary<string, object> _memo = new Dictionary<string, object>();
public object this[string key]
{
get
{
object o;
_memo.TryGetValue(key, out o);
return o;
}
}
public void UpdateState()
{
_memo["Name"] = Name;
_memo["Description"] = Description;
_memo["Alias"] = Alias;
_memo["Value"] = Value;
OnPropertyChanged("Item[]");
}
to make indexer this[]
work you have to rename class (e.g. to ItemVm
), because class name and member name can't be the same, and .NET uses "Item"
as indexer property name.
note that notifications for indexer have "Item[]"
format, and VerifyProperty()
method should be fixed too:
private void VerifyProperty(string propertyName)
{
if (propertyName == null || propertyName == "Item[]")
return;
now, to use unmodified value in window, bind to indexer like this:
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BackgroundColorConverterBool}">
<Binding Path="Value" />
<Binding Path="[Value]" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="LightBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
save initial state when creating items:
for(var i = 0; i < 100; i++)
{
Items.Add(new ItemVm
{
Alias = string.Format("Item {0}", i.ToString()),
Description = string.Format("Description {0}", i.ToString()),
Name = string.Format("Name {0}", i.ToString()),
Value = string.Format("Value {0}", i.ToString())
});
Items[i].UpdateState();
}
and save changes in state on button click:
private void Button_Click(object sender, RoutedEventArgs e)
{
UIHelper.UpdateDataBindings<Control>(this);
foreach(var item in Items)
{
item.UpdateState();
}
}