wpf,Datagrid,一列基于另外三列

时间:2014-10-07 06:01:10

标签: c# wpf xaml binding datagrid

我尝试将我的observablecollection绑定到datagrid。我想让最后一栏基于其他三个(column[n] = column[x]*column[y]*((column[z]+100)/100))这样的事情。我的第一个方法是在get部分中使用计算来制作属性,但却无法使UpdateSourceTrigger = PropertyChanged起作用。它仅在我转到另一行时才更新值。第二个方法是将最后一列i xaml绑定到那三个用多转换器计算但不知道如何使该绑定工作。 我认为第一个方法更好,所以有人可以告诉我为什么UpdateSourceTrigger = PropertyChanged不起作用,是否有某种技巧可以让它起作用?

修改

long ilosc;
public long Ilosc { 
    get { 
        return ilosc; 
    } 
    set {
        ilosc = value; Console.WriteLine("ilosc"); NotifyPropertyChanged("CenaBrutto"); 
    } 
}
float cena;
public float Cena { 
    get { 
        return cena; 
    } 
    set {
        cena = value; Console.WriteLine("cena"); NotifyPropertyChanged("CenaBrutto"); 
    } 
}
float vat;
public float Vat { 
    get { 
        return vat; 
    } 
    set {
        vat = value; Console.WriteLine("vat"); NotifyPropertyChanged("CenaBrutto"); 
    } 
}

public float CenaBrutto {
    get {
        return Cena * Ilosc * ((Vat + 100) / 100); ; 
    }
}

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string property) {
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

和xaml代码

<DataGrid ItemsSource="{Binding ElementName=fRoot, Path=Items, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Name="dgTU" Grid.Row="1"/>

1 个答案:

答案 0 :(得分:3)

  

所以有人可以告诉我为什么&#34; UpdateSourceTrigger = PropertyChanged&#34;   不工作

您完全误解了UpdateSourceTrigger的目的,特别是UpdateSourceTrigger.PropertyChanged

在数据绑定方案中,绑定源是一个对象,它为数据绑定提供数据值。另一方面,绑定目标是一个对象,它使用由绑定源提供的值。

WPF中的典型数据绑定用例假定,视图模型是绑定,控件是绑定目标

UpdateSourceTrigger设置更新绑定的模式(示例中的视图模型),而您的问题与更新目标({{1 }})。

  

是否有某种技巧可以让它发挥作用?

没有魔力 您的视图模型应该实现DataGrid,并且当其中一个相关属性更改了它的值时,您必须为计算属性引发INotifyPropertyChanged事件。这里是样本:

PropertyChanged

<强>更新

如果您的计算属性如下所示:

public class SomeClass : INotifyPropertyChanged
{
    public int A
    {
        get { return a; }
        set 
        {
            if (a != value)
            {
                a = value;
                OnPropertyChanged("A");
            }
        }
    }
    private int a;

    public int B
    {
        get { return b; }
        set 
        {
            if (b != value)
            {
                b = value;
                OnPropertyChanged("B");
            }
        }
    }
    private int b;

    public int C
    {
        get { return c; }
        private set
        {
            if (c != value)
            {
                c = value;
                OnPropertyChanged("C");
            }
        }
    }
    private int c;

    // INotifyPropertyChanged implementation
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }

        // update calculated property
        if (propertyName == "A" || propertyName == "B")
        {
            // this will cause binding target to re-read C value
            C = A + B;
        }
    }
}

即,没有设置器,只要在更改public int C { get { return A + B; } } OnPropertyChanged("C")的值后调用A就足够了:

B

更新2

请注意,您protected virtual void OnPropertyChanged(string propertyName) { // other stuff // update calculated property if (propertyName == "A" || propertyName == "B") { // this will cause binding target to re-read C value OnPropertyChanged("C"); } } 使用DataGrid(默认情况下)。在这种情况下,数据绑定表达式也使用默认值,AutoGenerateColumns="True"(将为DataGridTextColumn属性生成)float的{​​{1}}为UpdateSourceTrigger。你的建议是对的。

解决方法是将LostFocus设置为false,并手动设置所需的AutoGenerateColumns模式:

UpdateSourceTrigger

P.S。一点点说明。不要使用浮点类型(如 <DataGrid ItemsSource="{Binding ElementName=fRoot, Path=Items}" Name="dgTU" Grid.Row="1" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Ilosc, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Binding="{Binding Cena, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Binding="{Binding Vat, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Binding="{Binding CenaBrutto}"/> </DataGrid.Columns> </DataGrid> float)进行资金计算,请改用double