简体   繁体   中英

How can I add a calculated additional column in WPF DataGrid / ListView / ListBox

I have a DataGrid and a View Model ( MyViewModel1 ). The DataGrid is bound to the Items property of MyViewModel1 . The constraint is that I can not touch the code of MyViewModel1 and MyClass1 .

public class MyViewModel1 : INotifyPropertyChanged
{
    ...
    public ObservableCollection<MyClass1> Items { get { ... } }
    public int ViewModelProperty1 { get { ... } }
    public int ViewModelProperty2 { get { ... } }
}

public class MyClass1 : INotifyPropertyChanged
{
    ...
    public int Property1 { get { ... } }
    public int Property2 { get { ... } }
    public int Property3 { get { ... } }
}

I would like the DataGrid to show not just 3 columns with the 3 known properties, but also a 4th column on each row, which is dependent on Property1 , Property2 , Property3 , ViewModelProperty1 and ViewModelProperty2 . For the sake of the example let's say the 4th column is Property1 + Property2 + Property3 + ViewModelProperty1 + ViewModelProperty2 . The 4th column must show the current value, so if ViewModelProperty1 is increased by one, the 4th column must also be increased by one. My question is: What are my options to do this?

I can think of these:

  1. Use an IMultiValueConverter with all dependent variables as inputs. This works well for the example. The issue here is that as soon as the interaction of the variables becomes more complex eg ((Property1 + 2*Property2) * Property3) ^ (ViewModelProperty1 - ViewModelProperty2) , the order in which the 5 variables are put in the 'MultiBinding' becomes important and there is a lot of knowledge in the binding which can cause the the solution to become brittle.

  2. Use a wrapper. Bind the DataGrid to a new class MyViewModel2 , which registers to changes on MyViewModel1 , and looks something like

     public class MyViewModel2 { public MyViewModel2(MyViewModel1 m) { ... } ... public ObservableCollection<MyClass2> Items { get { ... } } } public class MyClass2 : INotifyPropertyChanged { public MyClass2(MyClass1 inner) { InnerClass = inner; InnerClass.NotifyPropertyChanged += InnerClassChanged; } void InnerClassChanged(object o, PropertyChangedEventArgs) { if (PropertyChanged != null) PropertyChanged("Property4"); } public void ViewModelPropertiesChanged { if (PropertyChanged != null) PropertyChanged("Property4"); } public MyClass1 InnerClass { get; private set; } public int Property4 { get { return InnerClass.Property1+InnerClass.Property2 ... } } public event PropertyChanged; } 

The question is what ways exist to solve this problem in addition to the 2 I mentioned above (Converter and Wrapper).

My question is not which way is the best way to solve the example.

Sorry, I just saw that you already thought of this! Not that I understand your objection.

You could use a MultiBinding with a IMultiValueConverter . See the example in the IMultiValueConverter documentation.

(From here: https://stackoverflow.com/a/2002598/360211 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM