2016-05-17 113 views
1

我有一個應用程序與WPF中的數據網格與C#,我有4列,我需要的是四列相對於其他列計算。我使用IValueConverter,它可以很好地工作,但是當我更改行時只計算第四列的值,而當我更改單元格2和3時,需要更改第4列。DataGrid中的計算列WPF

這是我的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(); 
    } 
} 

我該怎麼辦呢?

+1

你知道這些列中的值是從哪裏來的?你能澄清一下你的意思嗎?「馬上修改或更改第一列」? –

+0

我需要的是,當我在第一列更改值,然後第二列也更改值。 – asirvent

+0

你知道價值來自哪裏嗎?你是如何把他們放在網格中的? –

回答

-1

最後感謝埃德賓吉我在item類實現INotifyPropertyChangedPriceCount力來電OnPropertyChanged("TotalPrice")和完美的作品:

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; } 
    } 
} 
1

您必須爲此使用IValueConverter。使用第一列作爲源代碼(將第二列綁定到第一列)並使用轉換器轉換值。

MSDN example

4

您的Item類需要實現INotifyPropertyChanged,並在其任何屬性發生更改時提升PropertyChanged事件。

然後麻煩的是,綁定無法知道需要監視哪些屬性以進行更改。解決辦法之一是將您的轉換器更改爲IMultiValueConverter並將該綁定更改爲明確綁定PriceCountMultiBinding

您的另一種選擇,這將是一個更簡單的選項,將添加一個只讀TotalPrice屬性到您的Item類。這就是我會做的。

public decimal TotalPrice { 
    get { return Price * Count; } 
} 

然後,在你Price屬性,當Price變化,你將提高PropertyChanged事件TotalPrice以及爲Price。而你也會這樣做Count

然後,您可以非常簡單地在XAML中綁定到TotalPrice,根本沒有轉換器。您可能需要製作綁定Mode=OneWay,因爲它是隻讀的。

讓我知道你是否需要更多的代碼示例。