Update MultiBinding on DataGridCell

后端 未结 1 1933
抹茶落季
抹茶落季 2021-01-27 21:27

I am integrating property change detection in an application by way of MultiBinding and IMultiValueConverter. So when a user makes changes to a \'DataG

相关标签:
1条回答
  • 2021-01-27 22:21

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题