[DataGridCheckBoxColumn在属性更改时不会在MVVM中更新

问题描述 投票:-1回答:1

我正在使用的应用程序中有两个关键布尔值,以指示订单是否有效以待批准,然后指示该订单是否已被批准。我想要的是,当ObservableCollection的对象中的值更改时,复选框将在两列上更新,以便用户知道订单是否已准备好批准以及是否已经批准。

这些值会在模型中正确更新,并且视图模型中的批准按钮命令会按预期设置批准的布尔值,但是我无法获取复选框来动态更新。当前,它仅通过更改为其他视图然后再更改为订单视图来进行更新。

我仍在学习数据绑定和MVVM模型,因此我尝试了一些实验。到目前为止,我已经尝试了几种不同的方法来尝试获得我想要的行为,但是没有一个奏效。这是视图模型代码:

<UserControl x:Class="US_Wholesale_App_V2.Views.SPSOrderView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:US_Wholesale_App_V2.Views"
             xmlns:viewModels="clr-namespace:US_Wholesale_App_V2.ViewModels"
             xmlns:models="clr-namespace:US_Wholesale_App_V2.Models"
             mc:Ignorable="d" 
             d:DesignHeight="800" d:DesignWidth="1100">

    <UserControl.Resources>
        <DataTemplate DataType="{x:Type viewModels:SPSLineVM}">
            <local:SPSLineView/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModels:CustomerInfoVM}">
            <local:CustomerInfoView/>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="AUTO" MinWidth="312"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="AUTO"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel
            Orientation="Horizontal"
            HorizontalAlignment="Right"
            Grid.Row="0"
            Grid.Column="0">
            <Button
                Content="Lines"
                Height="20"
                Width="75"
                Margin="5,5,5,10"
                Command="{Binding SPSNavCommand}"
                CommandParameter="Lines"/>
            <Button
                Content="Shipping"
                Height="20"
                Width="75"
                Margin="5,5,5,10"
                Command="{Binding SPSNavCommand}"
                CommandParameter="Shipping"/>
        </StackPanel>

        <DataGrid
            x:Name="OrderHeaderGrid"
            AutoGenerateColumns="False"
            Margin="5"
            Grid.Row="1"
            Grid.Column="0"
            ItemsSource="{Binding SpsData}"
            SelectedItem="{Binding SelectedOrder, Mode=TwoWay}"
            CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn
                    Header="PO Number"
                    x:Name="PONumberCol"
                    Binding="{Binding PONumber}"/>
                <DataGridTextColumn
                    Header="Customer"
                    x:Name="CustomerCol"
                    Binding="{Binding Customer}"/>
                <DataGridTextColumn
                    Header="Retailer PO Number"
                    x:Name="RetailersPONumberCol"
                    Binding="{Binding RetailersPONumber}"/>
                <DataGridTextColumn
                    Header="DC Code"
                    x:Name="DCCodeCol"
                    Binding="{Binding DCCode}"/>
                <DataGridCheckBoxColumn
                    Binding="{Binding IsValid, Mode=OneWay}"
                    IsReadOnly="True"/>
                <DataGridTemplateColumn
                    Header="Approve">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button
                                Content="Approve"
                                Command="{Binding DataContext.ApproveButton, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
                                CommandParameter="{Binding SelectedOrder}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridCheckBoxColumn
                    Binding="{Binding IsApproved, Mode=OneWay}"
                    IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>
        <ContentControl
            Grid.Row="1"
            Grid.Column="1"
            Margin="5">
            <ContentControl Content="{Binding SPSCurrentVM}"/>
        </ContentControl>
    </Grid>
</UserControl>

如果有用,这里也是模型的代码。 RGLibrary项目只是我需要的通用类的库,例如SQL连接器或FTP方法。

using RGLibrary;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Threading.Tasks;

namespace US_Wholesale_App_V2.Models
{
    public class SPSOrderModel : Observable_Object, IDataErrorInfo
    {
        private bool _IsApproved;
        private string _PONumber;
        private string _RetailersPONumber;
        private string _PODate;
        private string _ShipDate;
        private string _CancelDate;
        private string _POPurpose;
        private string _POType;
        private string _VendorNumber;
        private string _Customer;
        private string _DCCode;
        private string _DepartmentNo;
        private ObservableCollection<SPSLineModel> _Lines;
        private BillingCustomerModel _BillingInfo;
        private ShippingCustomerModel _ShippingInfo;
        private ShippingChargesModel _Charges;


        public bool IsApproved
        {
            get { return _IsApproved; }
            set { _IsApproved = value; }
        }
        public string PONumber
        {
            get { return _PONumber; }
            set { _PONumber = value; }
        }
        public string RetailersPONumber
        {
            get { return _RetailersPONumber; }
            set { _RetailersPONumber = value; }
        }
        public string PODate
        {
            get { return _PODate; }
            set { _PODate = value; }
        }
        public string ShipDate
        {
            get { return _ShipDate; }
            set { _ShipDate = value; }
        }
        public string CancelDate
        {
            get { return _CancelDate; }
            set { _CancelDate = value; }
        }
        public string POPurpose
        {
            get { return _POPurpose; }
            set { _POPurpose = value; }
        }
        public string POType
        {
            get { return _POType; }
            set { _POType = value; }
        }
        public string VendorNumber
        {
            get { return _VendorNumber; }
            set { _VendorNumber = value; }
        }
        public string Customer
        {
            get { return _Customer; }
            set { _Customer = value; }
        }
        public string DCCode
        {
            get { return _DCCode; }
            set { _DCCode = value; }
        }
        public string DepartmentNo
        {
            get { return _DepartmentNo; }
            set { _DepartmentNo = value; }
        }
        public ObservableCollection<SPSLineModel> Lines
        {
            get { return _Lines; }
            set { _Lines = value; }
        }
        public BillingCustomerModel BillingInfo
        {
            get { return _BillingInfo; }
            set { _BillingInfo = value; }
        }
        public ShippingCustomerModel ShippingInfo
        {
            get { return _ShippingInfo; }
            set { _ShippingInfo = value; }
        }
        public ShippingChargesModel Charges
        {
            get { return _Charges; }
            set { _Charges = value; }
        }

        public string Error
        {
            get
            {
                var errorMsg = new StringBuilder();
                if (string.IsNullOrWhiteSpace(DepartmentNo))
                    errorMsg.AppendLine("The department number for this order cannot be blank");
                if (string.IsNullOrWhiteSpace(PODate))
                    errorMsg.AppendLine("You must enter a purchase order date");
                else if (!DateValidate("PODate", PODate))
                    errorMsg.AppendLine("The PO date format must be MM/DD/YYY");
                if (string.IsNullOrWhiteSpace(CancelDate))
                    errorMsg.AppendLine("You must enter a cancellation date");
                else if (!DateValidate("CancelDate", CancelDate))
                    errorMsg.AppendLine("The cancellation date format must be MM/DD/YYY");
                if (string.IsNullOrWhiteSpace(ShipDate))
                    errorMsg.AppendLine("You must enter a shipment date");
                else if (!DateValidate("ShipDate", ShipDate))
                    errorMsg.AppendLine("The shipment date format must be MM/DD/YYY");
                if (string.IsNullOrWhiteSpace(DCCode))
                    errorMsg.AppendLine("You must enter a DC code");
                if (Lines.Any(p => !p.IsValid))
                    errorMsg.AppendLine("You must correct all errors in the purchase order lines, or remove any lines with errors");
                if (SumDispatch(Lines) < 1)
                    errorMsg.AppendLine("The total dispatch quantity must be at least 1");
                return errorMsg.ToString();
            }
        }

        public bool IsValid
        {
            get
            {
                bool check = true;
                if (IsHeaderValid == false)
                    check = false;
                if (BillingValid == false)
                    check = false;
                if (ShippingValid == false)
                    check = false;
                if (ChargesValid == false)
                    check = false;
                if (LinesValid == false)
                    check = false;
                return check;
            }
        }

        public bool BillingValid
        {
            get
            {
                if (BillingInfo != null)
                    return BillingInfo.IsValid;
                else
                    return false;
            }
        }

        public bool ShippingValid
        {
            get
            {
                if (ShippingInfo != null)
                    return ShippingInfo.IsValid;
                else
                    return false;
            }
        }

        public bool ChargesValid
        {
            get
            {
                if (Charges != null)
                    return Charges.IsValid;
                else
                    return false;
            }
        }

        public bool LinesValid
        {
            get
            {
                bool check = true;
                if (Lines.Any(l => l.IsValid == false))
                    check = false;
                return check;
            }
        }

        public bool IsHeaderValid
        {
            get
            {
                bool check = true;
                if (string.IsNullOrWhiteSpace(PODate))
                    check = false;
                if (!DateValidate("PODate", PODate))
                    check = false;
                if (string.IsNullOrWhiteSpace(CancelDate))
                    check = false;
                if (!DateValidate("CancelDate", CancelDate))
                    check = false;
                if (string.IsNullOrWhiteSpace(ShipDate))
                    check = false;
                if (!DateValidate("ShipDate", ShipDate))
                    check = false;
                if (string.IsNullOrWhiteSpace(DCCode))
                    check = false;
                if (Lines.Any(p => !p.IsValid))
                    check = false;
                if (SumDispatch(Lines) < 1)
                    check = false;
                if (string.IsNullOrWhiteSpace(DepartmentNo))
                    check = false;
                return check;
            }
        }

        public string this[string name]
        {
            get
            {
                string result = null;
                if (name == "PODate")
                {
                    if (string.IsNullOrWhiteSpace(PODate))
                        result = "You must enter a date";
                    else if (!DateValidate("PODate", PODate))
                        result = "Date format must be MM/DD/YYY";
                }
                if (name == "CancelDate")
                {
                    if (string.IsNullOrWhiteSpace(CancelDate))
                        result = "You must enter a date";
                    else if (!DateValidate("CancelDate", CancelDate))
                        result = "Date format must be MM/DD/YYY";
                }
                if (name == "ShipDate")
                {
                    if (string.IsNullOrWhiteSpace(ShipDate))
                        result = "You must enter a date";
                    else if (!DateValidate("ShipDate", ShipDate))
                        result = "Date format must be MM/DD/YYY";
                }
                if (name == "DCCode")
                {
                    if (string.IsNullOrWhiteSpace(DCCode))
                        result = "You must enter a DC code";
                }
                return result;
            }
        }


        private static bool DateValidate(string sender, object value)
        {
            bool check = true;
            if (sender == "PODate" || sender == "CancelDate" || sender == "ShipDate")
            {
                string _date = value.ToString();
                string _expression = @"(([0]\d)|(11|12))\/(([012]\d)|(30|31))\/(20)\d{2}";
                Regex _Regex = new Regex(_expression);
                Match _match = _Regex.Match(_date);
                if (!_match.Success)
                    check = false;
            }

            return check;
        }

        private static int SumDispatch(ObservableCollection<SPSLineModel> lines)
        {
            int dispatchQty = 0;
            foreach (SPSLineModel line in lines)
            {
                dispatchQty += line.DispatchQty;
            }
            return dispatchQty;
        }
    }
}

c# wpf mvvm
1个回答
0
投票

正如问题中提到的最大,我需要在IsApproved和IsValid字段上实现PropertyChanged事件。对于IsApproved,这非常简单,因为我可以重用继承的Observable Object类中的事件:

© www.soinside.com 2019 - 2024. All rights reserved.