MVVM中的Datagrid绑定和编辑

时间:2016-01-07 04:13:00

标签: c# wpf xaml mvvm

我在尝试使用多年后使用代码后尝试启动MVVM。当PercentageComplete发生变化时,我试图让ThisClaimValue更新。 ThisClaimValue用于显示ContractAmt的百分比,基于PercentageComplete。无论是在人们投入价值还是离开牢房时。我试图用零代码来做这件事,所以没有内置事件。

我使用EF Database First作为Description,ContractAmt和BillCurrentAmt。 PercentComplete和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;

    }

编辑:添加了上面的完整视图模型代码。

2 个答案:

答案 0 :(得分:0)

要使其正常工作,请确保将JCCISelectedList指定为ObservableCollection以解决您的问题 否则,您需要为每个事件提高Property更改事件
Description
ContractAmt
....
每个元素分别作为raiseproperty更改事件不会生成任何元素更改事件作​​为{{的属性当元素更改其正在更改的datacontext时,1}}保持不变。

答案 1 :(得分:0)

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

因此,解决方案是使用Model类属性创建一个Model类包装表字段,如此

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

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