【问题标题】:Datagrid binding in MVVM and editingMVVM 中的 Datagrid 绑定和编辑
【发布时间】:2016-04-11 09:02:42
【问题描述】:

在使用了多年的代码后,我刚刚尝试从 MVVM 开始。我正在尝试在 PercentageComplete 更改时更新 ThisClaimValue。 ThisClaimValue 旨在显示 ContractAmt 的百分比,基于 PercentageComplete。无论是在人们投入价值的时候,还是在他们离开牢房的时候。我正在尝试使用零代码来执行此操作,因此没有内置事件。

我将 EF Database First 用于描述、ContractAmt 和 BillCurrentAmt。 PercentageComplete 和 ThisClaimValue 作为 EF 创建的类的部分类位于单独的解决方案中。

查看:

   <DataGrid Margin="10,10,10,0" RowDetailsVisibilityMode="VisibleWhenSelected" EnableRowVirtualization="True" AutoGenerateColumns="False" ItemsSource="{Binding JCCISelectedList, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding JCCI}" Grid.Row="3">
        <DataGrid.Columns>
            <DataGridTextColumn   Binding="{Binding Description}" Header="Description" Width="Auto" IsReadOnly="True"/>
            <DataGridTextColumn  Binding="{Binding ContractAmt}" Header="Value" Width="Auto" IsReadOnly="True"/>
            <DataGridTextColumn  Binding="{Binding PercentageComplete, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="% Complete" Width="Auto"/>
            <DataGridTextColumn  Binding="{Binding BillCurrentAmt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="$ Complete" Width="Auto"/>
            <DataGridTextColumn  Binding="{Binding ThisClaimValue}" Header="This Claim Value" Width="Auto" IsReadOnly="True"/>
        </DataGrid.Columns>
    </DataGrid>

视图模型:

  public class JBProgressBillItemsViewModel : INotifyPropertyChanged, IPageViewModel
    {
        public AcceptCommand AcceptEvent { get; set; }
        public BackCommand BackEvent { get; set; }
        public string Name => "JBProgressBillItems";

        public JBProgressBillItemsViewModel()
        {
            HQCOList = Facade.GetVistaHQCO();
            AcceptEvent = new AcceptCommand(this);
            BackEvent = new BackCommand(this);
        }
        private bHQCO _hqco;
        private bJCCM _jccm;
        private bJCCI _jcciSection;
        private bJCCI _jcci;

        public ObservableCollection<bHQCO> HQCOList { get; }
        public ObservableCollection<bJCCM> JCCMList { get; private set; }
        public ObservableCollection<bJCCI> JCCISectionList { get; private set; }
        public ObservableCollection<bJCCI> JCCIList { get; private set; }
        public ObservableCollection<bJCCI> JCCISelectedList { get; private set; }

        public bHQCO HQCO
        {
            get { return _hqco; }
            set
            {
                _hqco = value;
                JCCMList = Facade.GetVistaActiveProjects(_hqco.HQCo);
                RaisePropertyChanged(nameof(HQCO));
                RaisePropertyChanged(nameof(JCCMList));
            }
        }

        public bJCCM JCCM
        {
            get { return _jccm; }
            set
            {
                _jccm = value;
                JCCIList = Facade.GetVistaContractItems(_hqco.HQCo, _jccm.Contract);
                JCCISectionList =
                    new ObservableCollection<bJCCI>(JCCIList.Where(x => x.SICode == "H" || x.SICode == "SH"));
                RaisePropertyChanged(nameof(JCCM));
                RaisePropertyChanged(nameof(JCCISectionList));
            }
        }

        public bJCCI JCCISection
        {
            get { return _jcciSection; }
            set
            {
                _jcciSection = value;
                try
                {
                    JCCISelectedList = new ObservableCollection<bJCCI>(JCCIList.Where(x => _jcciSection.BillGroup == x.BillGroup && string.IsNullOrWhiteSpace(x.SICode)));
                }
                catch (ArgumentNullException)
                {
                }
                RaisePropertyChanged(nameof(JCCISection));
                RaisePropertyChanged(nameof(JCCISelectedList));
            }
        }

        public bJCCI JCCI
        {
            get { return _jcci; }
            set
            {
                _jcci = value;
                _jcci.ThisClaimValue = value.PercentageComplete * value.ContractAmt / 100;
                RaisePropertyChanged(nameof(JCCI));
                RaisePropertyChanged(nameof(JCCISelectedList));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public string Error => null;

    }

编辑:在上面添加了全视图模型代码。

【问题讨论】:

  • 什么是bJCCI JCCI?请详细说明。我的意思是这是一个模型对象吗?
  • 如果您会回应并澄清您的陈述,那么只有我们可以帮助您。
  • bJCCI 是 EF 中的一个表。

标签: c# wpf xaml mvvm


【解决方案1】:

要使其正常工作,请确保将 JCCISelectedList 指定为 ObservableCollection,这样可以解决您的问题。
否则,您需要为每个引发 Property changed 事件
Description
ContractAmt
....
每个元素单独作为 raiseproperty 更改事件不会为元素更改生成任何事件,因为JCCISelectedList 的属性在元素更改时保持不变正在发生变化的数据上下文。

【讨论】:

  • 我在上面添加了我的全视图模型代码。我把它作为一个 ObservableCollection。我的问题是 datagrid 没有更新该值。即使值保存在内存中。
  • 看起来@abhishek 回答了你的问题。如果您仍然遇到问题,那么带有示例 json 的示例项目会很棒。
【解决方案2】:

所以 bJCCI 是 EF 中的一个表,您希望 ThisClaimValue 在 PercentageComplete 更改时更新,其中 ThisClaimValue 和 PercentageComplete 是此表中的一个字段。在这里,您为表对象和集合调用 RaisePropertyChanged,而不是为特定字段值更改,如 ThisClaimValue 或 PercentageComplete。

所以解决方案是创建一个模型类,用模型类属性包装你的表字段,像这样

public class Model
{
    private bJCCI _jcci;
    public Double PerComplete
    {
        get { return _jcci.PercentageComplete ; }
        set
        {
            _jcci.PercentageComplete  = value;
            RaisePropertyChanged(nameof(PerComplete));
            RaisePropertyChanged(nameof(ClaimValue )); //Model property of ThisThisClaimValue field
        }
    }
}

现在,当 PerComplete 属性发生变化时,ClaimValue 属性将被更新并通知。 在 Xaml 中绑定这些 Model 的属性,不要直接使用 EF 模型类。

同样在 ViewModel 中创建

public ObservableCollection<Model> MyCollection { get; set; }

并将其与 DataGrid 项目源绑定。

请参考此链接; WPF MVVM INotifyPropertyChanged Implementation - Model or ViewModel

希望这会给你一个想法:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-27
    • 2015-08-06
    • 2021-07-07
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    相关资源
    最近更新 更多