2017-02-22 49 views
1

我有一个可编辑的数据网格列A和B.当添加一个新的项目/行,它没有任何意义的用户在列B中输入任何东西,直到他们在列A中输入的东西。有没有办法强制用户在创建新项目时首先初始化列A?我能够使用RowValidationRules很好,以确保列A已初始化,但我试图找到一种方法来完全防止这种情况。有没有办法在其他列之前强制输入WPF DataGrid列?

我还着眼于处理开始/准备单元格编辑事件和取消B列的编辑,直到A被初始化。问题在于用户可以为A输入一个值,但它尚未可见/待处理,并且尚未由DataGrid提交。

+1

您使用的是MVVM吗?你是否在CodeBehind中管理你的逻辑?只要列a无效,为什么不让列B只读?关于问题的问题 – lokusking

回答

1

假设这是你的模型

public class Model : INotifyPropertyChanged 
{ 
    string _desc; 
    public string Desc { get { return _desc; } set { _desc = value; RaisePropertyChanged("Desc"); } } 

    string _name; 
    public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } } 

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

,第一列绑定到Name,第二列绑定到Desc

<DataGrid.Columns> 
     <DataGridTextColumn Header="A" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/> 
     <DataGridTextColumn Header="B" Binding="{Binding Desc}"/> 
</DataGrid.Columns> 

你可以处理BeginningEdit事件,如你所说。请注意,在绑定第一列时,我设置了UpdateSourceTrigger=PropertyChanged。这解决了问题,您指出:

目前尚不可见/未决,并且尚未被DataGrid中

承诺现在你可以检查的要求,并在需要时取消它们。例如:

private void dg_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) 
    { 
     if (((DataGrid)sender).CurrentCell.Column.DisplayIndex == 1 && 
      ((Model)e.Row.Item).Name == null) 
     { 
      MessageBox.Show("Insert value of the first column first!"); 
      e.Cancel = true; 
     } 
    } 
0

你可以做到这一点使用DataGridTemplateColumn为列B.

<DataGridTemplateColumn> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=ColPropertyB}" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
    <DataGridTemplateColumn.CellEditingTemplate> 
     <DataTemplate> 
      <TextBox Text="{Binding Path=ColPropertyB}" 
        IsReadOnly="{Binding Path=ColPropertyA, Converter={StaticResource IsPropertyInvalidConverter}}" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellEditingTemplate> 
</DataGridTemplateColumn> 

而不是使用IsReadOnly属性,您也可以使用你想Visibility和多个UIElements或什么都。

第二种解决方案可以是使用CellEditingTemplateSelector和两个CellEdititingTempates。第一个是TextBlock(如果ColA无效),另一个是TextBoxTemplateSelector验证属性A并返回正确的模板。

<!-- DataGrid ResourceDictionary --> 
<DataTemplate x:Key="ValidTemplate"> 
    <TextBox Text="{Binding Path=ColPropertyB}" /> 
</DataTemplate> 
<DataTemplate x:Key="InvalidTemplate"> 
    <TextBlock Text="{Binding Path=ColPropertyB}" /> 
</DataTemplate> 
<ColBTemplateSelector x:Key="ColBTemplateSelector" 
     ValidDataTemplate="{StaticResource ValidTemplate}" 
     InvalidDataTemplate="{StaticResource InvalidTemplate}" /> 

<!-- DataGridColumns --> 
<DataGridTemplateColumn CellEditingTemplateSelector="{StaticResource ColBTemplateSelector}"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=RowPropertyB}" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

TemplateSelector

public class ColBTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate ValidDataTemplate { get; set; } 
    public DataTemplate InvalidDataTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var tempItem = (item as YourDataItem); 
     if (tempItem == null || tempItem.IsColPropertyAInvalid()) return InvalidDataTemplate; 
     return ValidDataTemplate; 
    } 
} 

随着TemplateSelector我不知道如果进入编辑模式时,它总是被称为...

+0

我喜欢第一个解决方案,但我不确定如何绑定IsReadOnly =“{Binding Path = ColPropertyA ...”。你需要一个相对来源。 – Dan

+0

您可以在写入时绑定它。列的'DataContext'是项目,您可以绑定到每个属性。验证在'IsPropertyInvalidConverter'完成。该转换器需要返回'布尔值'如果有效或不... – WPFGermany

相关问题