WPF + Datagrid + CellUpdate:如何以编程方式实现

时间:2017-01-18 02:18:48

标签: c# wpf data-binding wpfdatagrid

我有一个WPF应用程序。像这样:

            <DataGrid x:Name="MetroDataGrid"
                      CanUserReorderColumns="False"
                      Grid.Row="1"
                      ScrollViewer.CanContentScroll="True"
                      ScrollViewer.VerticalScrollBarVisibility="Visible"
                      ScrollViewer.HorizontalScrollBarVisibility="Visible"
                      Grid.Column="1"
                      CanUserResizeRows="False"
                      CanUserDeleteRows="True"
                      Margin="1"
                      AutoGenerateColumns="False"
                      HeadersVisibility="All"
                      ItemsSource="{Binding Path=Invoicelines, Mode=TwoWay}"
                      CanUserSortColumns="False"
                      SelectionUnit="FullRow">

Invoicelines是我的viewmodel类中的ObservableCollection属性。

此网格包含三列:必须汇总其中两列,第三列应包含结果。

请注意,我的ViewModelClass现在实现了INotifyPropertyChanged接口。

我尝试了CellEditEnding事件,但仍然无法得到数据网格的特定行,第三个单元格从前两个单元格更新。

你怎么解决这个问题?

编辑(部分工作..现在问题是因为我已经为所有列附加了Cantidad properyy,然后在更改此列中的单元格时所有行,将此更改传递给其余的同一列中的行... 我还缺少什么?)

XAML

                <DataGridTemplateColumn Header="Cant." 
                                        Width="100"
                                        MinWidth="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Controls:NumericUpDown Value="{Binding DataContext.Cantidad, UpdateSourceTrigger=PropertyChanged,RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
                                                    Minimum="0"
                                                    Interval="0.5"
                                                    StringFormat="0.000"
                                                    HideUpDownButtons="True"
                                                    ></Controls:NumericUpDown>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

视图模型

class InvoiceViewModel : ViewModelBase
{
    private ObservableCollection<InvoiceLine> invoicelines;

    public ObservableCollection<InvoiceLine> Invoicelines{
        set {
            invoicelines = value;
            OnPropertyChanged("Invoicelines");
        }
        get { return invoicelines; }
    }

    public decimal Cantidad {
        get { return cantidad; }
        set {
            if (Equals(value, cantidad)) return;
            cantidad = value;
            OnPropertyChanged();
        }
    }

    public decimal Preciounit {
        get { return preciounit; }
        set
        {
            if (Equals(value, preciounit)) return;
            preciounit = value;
            OnPropertyChanged();
        }
    }
}

ViewModelBase

class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

模型

public class InvoiceLine
{
    public decimal Cantidad { get; set; }
    public decimal Preciounit { get; set; }
    public decimal Subtotal { get; set; }
}

2 个答案:

答案 0 :(得分:1)

  

我尝试使用第一列:<DataTemplate> <Controls:NumericUpDown Value="{Binding Cantidad2}"></Controls:NumericUpDown> </DataTemplate>。但是当我调试编译器时还没有进入Cantidad2属性..我错过了什么吗?

如果您使用MahApps的NumericUpDown,您应该尝试将绑定的UpdateSource属性设置为PropertyChanged:

<controls:NumericUpDown Value="{Binding Cantidad2, UpdateSourceTrigger=PropertyChanged}" />

然后应调用Cantidad2属性的setter,前提是“Invoicelines”集合中的数据对象实际上具有相应类型的名为“Cantidad2”的属性(可能double,具体取决于NumericUpDown控件你正在使用)。

编辑:如果要绑定到InvoiceViewModel类的属性,则应使用RelativeSource:

<controls:NumericUpDown Value="{Binding DataContext.Cantidad, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=DataGrid}}" />

答案 1 :(得分:0)

如果我理解正确,您正尝试更改前两列并将结果显示到第三列。

您的计算逻辑在哪里?

您可以将前两个与VM属性绑定,第三个与计算值绑定(单向绑定)。

当更新前两个属性的值时,将自动更新第三个值。您需要在所有三个事件中引发PropertyChanged事件。

           <DataGridTemplateColumn Header="FirstValue">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding FirstValue}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

           <DataGridTemplateColumn Header="SecondValue">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding SecondValue}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>                    

            <DataGridTemplateColumn Header="ThirdValue">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding ThirdValue, Mode=OneWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>