0

I have DataGrid with 5 columns. Value of some column depends on other columns. how to create this dependency? I have tried to implement this structure, which fills data grid. But it was not updated in the case when other cells were eddited.

public class ColorItem
{
    //  Constructor
    /*
     *      ColorItem constructor
     *      Params: color name, color
     */
    public ColorItem(string color_name, Color color)
    {
        ItemName = color_name;
        RChanel = color.R;
        GChanel = color.G;
        BChanel = color.B;
    }

    //  Item name
    public string ItemName { get; set; }
    //  Item color (calculated item)
    public Brush ItemColor { get { return new SolidColorBrush(Color.FromRgb(RChanel, GChanel, BChanel)); } }
    //  Item r chanel
    public byte RChanel { get; set; }
    //  Item g chanel
    public byte GChanel { get; set; }
    //  Item b chanel
    public byte BChanel { get; set; }

}
Alex Aparin
  • 4,393
  • 5
  • 25
  • 51

1 Answers1

1

I don't think it's a good idea to use Brush in ViewModel (talking about MVVM), rather use multiconverter or e.g. Color + ColorToSolidBrushConverter.

But in any case you do not rise notification when you change property, so View doesn't know when to update.

Fixed version:

public class ColorItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string property = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));

    public Brush ItemBrush => new SolidColorBrush(Color.FromRgb(R, G, B));

    byte _r;
    public byte R 
    {
        get { return _r; }
        set
        {
            _r = value;
            OnPropertyChanged(); // this will update bindings to R
            OnPropertyChanged(nameof(ItemBrush)); // this will update bindings to ItemBrush
        }
    }

    ... // same for G and B
}
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • I have added notification. But I cannot understand, who should handle notification and how – Alex Aparin Aug 11 '16 at 15:05
  • You said *"I used bindings to create such grid's data"*, so I assumed you have `DataGrid.ItemsSource` bound to property of `ObservableCollection` (if collection is not changed, then a simple `List` will do). If that's true, then you only lack `INotifyPropertyChanged`. And that's what my answer is about. – Sinatr Aug 11 '16 at 15:28
  • Yes, you are right. I have DataGrid.ItemsSource as ObservableCollection. – Alex Aparin Aug 11 '16 at 15:32
  • Does it work? Maybe you have problem with xaml (show it) or binding (show the property you are binding to). – Sinatr Aug 11 '16 at 15:34
  • I have PropertyChanged public event in ColorItem, but I don't know which handler I should set. Notification should call event handler – Alex Aparin Aug 11 '16 at 15:38
  • You don't need to. As soon as you bind `ItemsSource` to `ObservableCollection` any `DataGridRow` will subscribe to `NotifyPropertyChanged` (in the View). That's how WPF binding works. – Sinatr Aug 11 '16 at 15:40
  • I found that ItemsSource is changed but DataGrid is not updated. I create items source via: data_grid.ItemsSource = color_records; – Alex Aparin Aug 11 '16 at 16:38
  • 1
    Don't set `DataSource` directly. Use binding (either in xaml or in code behind). – Sinatr Aug 12 '16 at 06:52
  • It seems like I understood my problem. Documentation says - Note that the ItemsSource property supports OneWay binding by default. – Alex Aparin Aug 12 '16 at 07:16
  • You was right, I just updated wrong name of property. You approach is completely correct – Alex Aparin Aug 12 '16 at 09:01