2014-07-14 182 views
0

我正在創建一個列表存儲在列表中的DataTableMVVM WPF:驗證自動生成列的數據網格行

public class CustomColumn 
{ 
    public string ColumnName { get; set; } 
    public int MinLength { get; set; } 
    public int MaxLength { get; set; } 
} 

public class ViewModel 
{ 
    public List<CustomColumn> Columns { get; set; } 
    public DataTable MyTable { get; set; } 

    public ViewModel() 
    { 
     InitializeCustomColumns(); 
     MyTable = new DataTable(); 

     foreach (CustomColumn column in Columns) 
     { 
      MyTable.Columns.Add(column.ColumnName, typeof(string)); 
     } 
    } 
} 

現在我結合了DataTableDataGrid,並允許用戶在DataGrid添加行。我的DataGrid列列是在運行時初始化時自動生成的。當用戶在該行的特定列中輸入某個值時,我想根據CustomColumn屬性 - >MinLength(最小字符串長度)& MaxLength(允許的最大字符串長度)進行驗證。如果驗證失敗,我想顯示DataGrid中出現的默認紅色邊框以顯示無效輸入。我遵循MVVM軟件架構模式。

編輯

我連着ColumnChanging監聽

MyTable.ColumnChanging += tableColumnChanging; 

private void tableColumnChanging(object sender, DataColumnChangeEventArgs e) 
{ 
    //I am able to validate here using my logic 
    if(!isValid(e)) 
    { 
     object badValue = e.ProposedValue; 
     e.ProposedValue = "Bad Data"; 
     e.Row.RowError = "The column contains an error"; 
     e.Row.SetColumnError(e.Column, "Column cannot be " + badValue); 
    } 
    else 
    { 
     ... 
    } 

} 

我能夠證實,但我想我的顯示與細胞!標記isValid是否返回false。

+0

-1 Abhishek,你現在應該知道,這是*不是一個網站,你可以來說*這是我想要*,並期望其他用戶爲你做你的工作。 *你*需要做這項工作,並且只是來問問你是否被困在某個特定的部分。因此,我建議您儘量滿足您的要求,如果您遇到困難,則應提供[*所有相關代碼*](http://stackoverflow.com/help/mcve)以說明您的問題。 – Sheridan

+0

@Sheridan我知道我在問很多問題。但是,我只是在完成全面的研究後才問。我目前的WPF應用程序有點複雜,因此我在嘗試簡化問題並提供我的問題簡化示例之前。有些東西只是在我的頭上。 –

+0

阿布舍克,這不是關於*問很多問題* ...它是關於要求代碼的,而沒有表明你自己做了一個嘗試。正如你現在提供了你的相關代碼,我現在將刪除我的投票,儘管你的代碼仍然不完整,不會重現你的問題。 – Sheridan

回答

1

嗯,我設法爲同一

XAML做一個變通方法

<ScrollViewer xmlns:l="clr-namespace:CSharpWPF"> 
    <ScrollViewer.Resources> 
     <DataTemplate DataType="{x:Type l:CustomTable}"> 
      <DataTemplate.Resources> 
       <l:ErrorToVisibilityConverter x:Key="ErrorToVisibilityConverter" /> 
       <Style TargetType="DataGridCell"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="DataGridCell"> 
           <Grid Background="{TemplateBinding Background}"> 
            <StackPanel Orientation="Horizontal"> 
             <TextBlock Text=" ! " 
                FontWeight="Bold" 
                Foreground="Red"> 
              <TextBlock.Visibility> 
               <MultiBinding Converter="{StaticResource ErrorToVisibilityConverter}" 
                   Mode="OneWay"> 
                <Binding RelativeSource="{RelativeSource FindAncestor,AncestorType=DataGridCell}" /> 
                <Binding Path="Tag.Errors" 
                  RelativeSource="{RelativeSource FindAncestor,AncestorType=DataGrid}" /> 
                <Binding /> 
               </MultiBinding> 
              </TextBlock.Visibility> 
             </TextBlock> 
             <ContentPresenter /> 
            </StackPanel> 
           </Grid> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </DataTemplate.Resources> 
      <StackPanel> 
       ... 
      </StackPanel> 
     </DataTemplate> 
    </ScrollViewer.Resources> 
    <ContentControl Content="{Binding TableCollection}" /> 
</ScrollViewer> 

我已經添加了DataGridCell一個Style和定義的自定義Template我們額外的元素顯示!馬克

轉換器類

namespace CSharpWPF 
{ 
    public class ErrorToVisibilityConverter : IMultiValueConverter 
    { 
     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
     { 
      DataGridColumn column = values[0] as DataGridColumn; 
      ObservableCollection<DataColumnChangeEventArgs> errors = values[1] as ObservableCollection<DataColumnChangeEventArgs>; 
      DataRowView view = values[2] as DataRowView; 

      DataColumnChangeEventArgs args = errors.FirstOrDefault(e => (e.Row == view.Row) && (e.Column.Ordinal == column.DisplayIndex)); 

      return view.Row.HasErrors && args != null ? Visibility.Visible : Visibility.Collapsed; 
     } 

     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

這將檢測如果當前小區是其中受影響的一個,並返回Visibility.Visible如果爲真,否則Visibility.Collapsed因此隱藏或顯示

變化在CustomTable

public CustomTable() 
{ 
    ... 

    Errors = new ObservableCollection<DataColumnChangeEventArgs>(); 
} 

private void tableColumnChanging(object sender, DataColumnChangeEventArgs e) 
{ 
    if (!isValid(e)) 
    { 
     object badValue = e.ProposedValue; 
     e.ProposedValue = "Bad Data"; 
     e.Row.RowError = "The column contains an error"; 
     e.Row.SetColumnError(e.Column, "Column cannot be " + badValue); 
     Errors.Add(e); 
     OnPropertyChanged("Errors"); 
    } 
    else 
    { 
     DataColumnChangeEventArgs args = Errors.FirstOrDefault(ee => (ee.Row == e.Row) && (ee.Column == e.Column)); 
     if (args != null) 
     { 
      Errors.Remove(args); 
      OnPropertyChanged("Errors"); 
     } 
     //... 
    } 
} 

public ObservableCollection<DataColumnChangeEventArgs> Errors { get; set; } 

根據錯誤狀態的額外元件結果

result

所以整個想法是與通知符添加額外的屬性改變能力並將其用作觸發器和其他屬性來檢測適當的列,而休息是我們額外的可見性!元素在自定義模板

+0

想知道這是否解決了你的問題? – pushpraj