Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# wpf Datagrid:抛出重复项_C#_Wpf_Validation_Datagrid - Fatal编程技术网

C# wpf Datagrid:抛出重复项

C# wpf Datagrid:抛出重复项,c#,wpf,validation,datagrid,C#,Wpf,Validation,Datagrid,在我的应用程序中,当我在单元格中输入新项时,我想验证用户是否输入了DataGrid中已经存在的项。我使用IDataErrorInfo验证我的业务对象 我的目标如下: class clsProducts : INotifyPropertyChanged, IDataErrorInfo { private string _ProductName; private decimal _PurchaseRate; private int _AvailableQty; pr

在我的应用程序中,当我在单元格中输入新项时,我想验证用户是否输入了DataGrid中已经存在的项。我使用
IDataErrorInfo
验证我的业务对象

我的目标如下:

 class clsProducts : INotifyPropertyChanged, IDataErrorInfo
{
    private string _ProductName;
    private decimal _PurchaseRate;
    private int _AvailableQty;
    private int _Qty;
    private decimal _Amount;

    #region Property Getters and Setters

    public string ProductName
    {
        get { return _ProductName; }
        set
        {

            if (_ProductName != value)
            {
                _ProductName = value;
                OnPropertyChanged("ProductName");
            }
        }
    }

    public decimal PurchaseRate
    {
        get { return _PurchaseRate; }
        set
        {
            _PurchaseRate = value;
            OnPropertyChanged("PurchaseRate");
        }
    }

    public int AvailableQty
    {
        get { return _AvailableQty; }
        set
        {
            _AvailableQty = value;
            OnPropertyChanged("AvailableQty");
        }
    }

    public int Qty
    {
        get { return _Qty; }
        set
        {
            _Qty = value;
            this._Amount = this._Qty * this._PurchaseRate;
            OnPropertyChanged("Qty");
            OnPropertyChanged("Amount");
        }
    }

    public decimal Amount
    {
        get { return _Amount; }
        set
        {
            _Amount = value;
            OnPropertyChanged("Amount");
        }
    }

    #endregion

    #region IDataErrorInfo Members

    public string Error
    {
        get
        {
            StringBuilder error = new StringBuilder();
            // iterate over all of the properties
            // of this object - aggregating any validation errors
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(this);
            foreach (PropertyDescriptor prop in props)
            {
                string propertyError = this[prop.Name];
                if (!string.IsNullOrEmpty(propertyError))
                {
                    error.Append((error.Length != 0 ? ", " : "") + propertyError);
                }
            }
            return error.ToString();
        }
    }

    public string this[string name]
    {
        get
        {
            string result = null;

            if (name == "ProductName")
            {
                if (this._ProductName != null)
                {
                    int count = Global.ItemExist(this._ProductName);
                    if (count == 0)
                    {
                        result = "Invalid Product "+this._ProductName;
                    }
                }
            }

            else if (name == "Qty")
            {
                if (this._Qty > this._AvailableQty)
                {
                    result = "Qty must be less than Available Qty . Avaialble Qty : " + this._AvailableQty;
                }
            }

            return result;
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    // Declare the event
    public event PropertyChangedEventHandler PropertyChanged;

    //// Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    #endregion
}
我的xaml是:

 <my:DataGrid Name="dgReceiveInventory" RowStyle="{StaticResource RowStyle}"  ItemsSource="{Binding}" GotFocus="dgReceiveInventory_GotFocus"  CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False"  RowHeight="23"  SelectionUnit="Cell"   AutoGenerateColumns="False" Margin="12,84,10,52"  BeginningEdit="dgReceiveInventory_BeginningEdit">
        <my:DataGrid.Columns>

            <!--0-Product Column-->

            <my:DataGridTemplateColumn Header="Product Name" Width="200">
                <my:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Style="{StaticResource TextBlockInError}" Text="{Binding ProductName,ValidatesOnDataErrors=True}"  ></TextBlock>
                    </DataTemplate>
                </my:DataGridTemplateColumn.CellTemplate>
                <my:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox x:Name="txtbxProduct" Style="{StaticResource TextBoxInError}" Text="{Binding Path=ProductName,UpdateSourceTrigger=LostFocus,ValidatesOnDataErrors=True}"  TextChanged="txtbxProduct_TextChanged" PreviewKeyDown="txtbxProduct_PreviewKeyDown" >
                                    </TextBox>
                    </DataTemplate>
                </my:DataGridTemplateColumn.CellEditingTemplate>
            </my:DataGridTemplateColumn>

            <!--1-Purchase Rate Column-->
            <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}" IsReadOnly="True"></my:DataGridTextColumn>

            <!--2-Avaialable Qty Column-->
            <my:DataGridTextColumn Header="AvailableQty"  Binding="{Binding AvailableQty}" IsReadOnly="True" Visibility="Hidden"></my:DataGridTextColumn>

            <!--3-Qty Column-->

            <my:DataGridTextColumn Header="Qty"  Binding="{Binding Qty,ValidatesOnExceptions=True,ValidatesOnDataErrors=True}" EditingElementStyle="{StaticResource TextBoxInError}">

            </my:DataGridTextColumn>

            <!--4-Amount Column-->
            <my:DataGridTextColumn Header="Amount" Width="100"  Binding="{Binding Amount}" ></my:DataGridTextColumn>
        </my:DataGrid.Columns>
    </my:DataGrid>


现在,我想向用户展示,如果他在datagrid单元格中创建了一个重复条目,如何执行此操作?

您不能使用
IDataErrorInfo
界面在模型或数据类型类中执行此功能,因为您无法访问其中的其他对象。相反,您必须在视图模型中执行此操作。但是,您可以使用该接口报告错误。我通过在数据类型基类中添加属性扩展了其功能:

public virtual ObservableCollection<string> ExternalErrors
{
    get { return externalErrors; }
}
然后我将其“插入”到我的
Errors
属性中:

public override ObservableCollection<string> Errors
{
    get
    {
        errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["Name"]);
        errors.AddUniqueIfNotEmpty(this["EmailAddresses"]);
        errors.AddUniqueIfNotEmpty(this["StatementPrefixes"]);
        errors.AddRange(ExternalErrors);
        return errors;
    }
}
顺便说一句,只调用实际正在验证的索引器要比使用反射调用所有属性的示例有效得多。然而,这是你的选择

现在我们有了这个
ExternalError
属性,我们可以使用它来显示视图模型中的外部错误消息(创建一个包含集合属性的类来绑定到
DataGrid.ItemsSource
属性)

如果使用的是
ICommand
对象,则可以将此代码放入Save命令的
CanExecute
方法中:

public bool CanSave(object parameter)
{
    clsProducts instance = (clsProducts)parameter;
    instance.ExternalError = YourCollectionProperty.Contains(instance) ? 
        "The values must be unique" : string.Error;
    // Perform your can save checks here
}

请注意,您需要在数据类型对象中实现
Equals
方法才能使其工作。有许多类似的方法可以实现这一点,我相信从这个例子中,您将能够找到一个适合您的方法。

那么问题是什么?1)发布xaml 2)到目前为止您尝试了什么?3) 您在哪里遇到问题?请查看我编辑的问题
public override string Error
{
    get
    {
        error = string.Empty;
        if ((error = this["Name"])) != string.Empty) return error;
        if ((error = this["EmailAddresses"])) != string.Empty) return error;
        if ((error = this["Name"])) != string.Empty) return error;
        if (ExternalError != string.Empty) return ExternalError;
        return error;
    }
}
public bool CanSave(object parameter)
{
    clsProducts instance = (clsProducts)parameter;
    instance.ExternalError = YourCollectionProperty.Contains(instance) ? 
        "The values must be unique" : string.Error;
    // Perform your can save checks here
}