簡體   English   中英

DataGrid WPF中的計算列

[英]Calculated column in datagrid WPF

我有一個帶有C#的WPF中具有數據網格的應用程序,我有4列,我需要相對於其他列計算這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();
    }
}

我該怎么做?

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

然后的麻煩是,該綁定無法知道它需要監視哪些屬性。 一種解決方案是將您的轉換器更改為IMultiValueConverter ,並將該綁定更改為一個顯式綁定PriceCountMultiBinding

對您來說,這是一個更簡單的選擇,它是向您的Item類添加一個只讀的TotalPrice屬性。 那就是我會做的。

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

然后,在Price屬性中,當Price變化時,您將引發TotalPricePricePropertyChanged事件。 您也可以對Count做同樣的事情。

然后,您可以在XAML中非常簡單地綁定到TotalPrice ,而無需任何轉換器。 您可能需要設置綁定Mode=OneWay ,因為它是只讀的。

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

您必須為此使用IValueConverter 將第一列用作源(將第二列綁定到第一列),然后使用轉換器轉換值。

MSDN示例

最后,感謝Ed Plunkett,我在我的item類中實現了INotifyPropertyChanged ,並在Price and Count實現了對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;  }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM