我在WPF中使用带有C#,I' 4列的数据网格的应用程序,我需要相对于其他列计算四列。我使用的是IValueConverter,它可以很好地工作,但是当我更改行时只计算第四列的值,而当我更改单元格2和3时,我需要更改4列。
这是我的XAML:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication6"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="grid">
<DataGrid.Resources>
<local:CalculatingConverter x:Key="CalculatingConverter" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" />
<DataGridTextColumn Binding="{Binding Count}"/>
<DataGridTextColumn Binding="{Binding Price}" />
<DataGridTextColumn
Header="Total"
Binding="{Binding Converter={StaticResource CalculatingConverter}}"
/>
</DataGrid.Columns>
</DataGrid>
</Grid>
这是我的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Item> items = new List<Item>();
items.Add(new Item() { Name = "Item1", Count = 2, Price = 10 });
items.Add(new Item() { Name = "Item2", Count = 5, Price = 20 });
this.grid.ItemsSource = items;
}
}
public class Item : INotifyPropertyChanged
{
private string name;
private decimal price;
private int count;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string Name {
get
{
return this.name;
}
set
{
if (value != name)
{
name = value;
OnPropertyChanged();
}
}
}
public decimal Price
{
get
{
return price;
}
set
{
if (value != this.Price)
{
price = value;
OnPropertyChanged();
}
}
}
public int Count {
get
{
return count;
}
set
{
if (value != count)
{
count = value;
OnPropertyChanged();
}
}
}
public decimal TotalPrice
{
get { return Price * Count; }
}
}
这是我的IConverter:
public class CalculatingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
return ((Item)value).Price * ((Item)value).Count;
}
catch
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
我该怎么做?
答案 0 :(得分:4)
您的Item
类需要实现INotifyPropertyChanged
并在其任何属性发生更改时引发PropertyChanged
事件。
然后麻烦的是,该绑定无法知道需要监视更改的属性。一种解决方案是将转换器更改为IMultiValueConverter
,并将绑定更改为MultiBinding
,该Price
明确绑定Count
和TotalPrice
。
另一个选项,这将是一个更简单的选项,就是向您的Item
类添加只读public decimal TotalPrice {
get { return Price * Count; }
}
属性。这就是我要做的。
Price
然后,在Price
媒体资源中,当PropertyChanged
发生变化时,您会引发TotalPrice
以及Price
的{{1}}事件。你会对Count
做同样的事情。
然后你可以非常简单地在XAML中绑定到TotalPrice
而根本没有转换器。您可能需要进行绑定Mode=OneWay
,因为它是只读的。
如果您需要更多代码示例,请与我们联系。
答案 1 :(得分:1)
你必须使用IValueConverter
。使用第一列作为源(将第二列绑定到第一列)并使用转换器转换值。
答案 2 :(得分:-1)
最后感谢Ed Plunkett,我在我的INotifyPropertyChanged
课程中item
和Price
强制Count
强制调用OnPropertyChanged("TotalPrice")
并完美地运作:< / p>
public class Item : INotifyPropertyChanged
{
private string name;
private decimal price;
private int count;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string Name {
get
{
return this.name;
}
set
{
if (value != name)
{
name = value;
OnPropertyChanged();
}
}
}
public decimal Price
{
get
{
return price;
}
set
{
if (value != this.Price)
{
price = value;
OnPropertyChanged();
OnPropertyChanged("TotalPrice");
}
}
}
public int Count {
get
{
return count;
}
set
{
if (value != count)
{
count = value;
OnPropertyChanged();
OnPropertyChanged("TotalPrice");
}
}
}
public decimal TotalPrice
{
get { return Price * Count; }
}
}