2017-02-25 38 views
0

我已經創建了多行和多列的數據網格。其中一列是用戶可以更改的字段大小列表。如何根據以前的值驗證數據網格值

我正在檢查舊值的新值,如果新值小於舊值我告訴用戶這是無效的,然後我想把舊值重新設置,並重新設置爲重點細胞。

我有這行我LostFocus事件:

System.Windows.Controls.TextBox tbNewSize = 
    (System.Windows.Controls.TextBox)dtgCell.Content; 

當我點擊單元格中,LostFocus事件被稱爲和工作正常。但是,當我嘗試重新調整單元格時,出現一條錯誤消息:

「無法將類型爲」System.Windows.Controls.TextBlock「的對象轉換爲鍵入」System.Windows.Controls.TextBox「。

如何解決此問題?

這裏是我的XAML代碼:

<DataGrid HeadersVisibility="Column" Name="dtGrid" Loaded="GridLoaded" AutoGenerateColumns="False" IsReadOnly="False" VirtualizingPanel.IsVirtualizing="False" Height="365" Width="530" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="54,74,0,0" BorderThickness="1,1,0,1" BorderBrush="Black"> 
<DataGrid.Columns> 
    <DataGridTextColumn Header="Field" Binding="{Binding Field, Mode=TwoWay}" Width="209" IsReadOnly="True" /> 
    <DataGridTextColumn Header="Size" Binding="{Binding Size, Mode=TwoWay}" Width="89"/> 
    <DataGridCheckBoxColumn Header="Right Justify" Binding="{Binding RightJustify, Mode=TwoWay}" Width="55" /> 
    <DataGridCheckBoxColumn Header="Left Justify" Binding="{Binding LeftJustify, Mode=TwoWay}" Width="55" /> 
    <DataGridCheckBoxColumn Header="Left Zero Fill" Binding="{Binding LeftZeroFill, Mode=TwoWay}" Width="55" /> 
    <DataGridCheckBoxColumn Header="Right Zero Fill" Binding="{Binding RightZeroFill, Mode=TwoWay}" Width="65" /> 
</DataGrid.Columns> 
<DataGrid.ColumnHeaderStyle> 
    <Style TargetType="DataGridColumnHeader"> 
     <Setter Property="ContentTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <TextBlock TextWrapping="Wrap" Text="{Binding}"></TextBlock> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</DataGrid.ColumnHeaderStyle> 
<DataGrid.Resources> 
    <Style TargetType="{x:Type DataGridCell}"> 
     <Style.Triggers> 
      <Trigger Property="DataGridCell.IsSelected" Value="True"> 
       <Setter Property="Background" Value="#FF9DF3D6" /> 
       <Setter Property="Foreground" Value="#000000" /> 
      </Trigger> 
     </Style.Triggers> 
     <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" /> 
     <EventSetter Event="LostFocus" Handler="DataGridCell_OnCellLostFocus" /> 
    </Style> 
</DataGrid.Resources> 

這裏是我的C#代碼:

private void DataGridCell_OnCellLostFocus(object sender, RoutedEventArgs e) 
{ 
    System.Windows.Controls.DataGridCell dtgCell = (System.Windows.Controls.DataGridCell)sender; 

    if (dtgCell.Column.Header.ToString() == "Size") 
    { 
     System.Windows.Controls.TextBox tbNewSize = (System.Windows.Controls.TextBox)dtgCell.Content; 
     Int32 intNewSize = Convert.ToInt32(tbNewSize.Text); 
     Int32 intCurrSize = Convert.ToInt32(strFieldInfoOrig[dtGrid.Items.IndexOf(dtGrid.CurrentItem), 1]); 

     if (intNewSize < intCurrSize) 
     { 
      string strMsg; 

      strMsg = "New size, " + intNewSize.ToString() + " is smaller then the original size, " + intCurrSize.ToString(); 
      strMsg += Environment.NewLine; 
      strMsg += "Due to potential data loss, this is not allowed."; 
      System.Windows.MessageBox.Show(strMsg); 
      //dtgCell.Content = intCurrSize.ToString(); 
      dtgCell.Focus(); 
     } 
    } 
} 
+0

我正在上的錯誤這行'Int32 intCurrSize = Convert.ToInt32(strFieldInfoOrig [dtGrid.Items.IndexOf(dtGrid.CurrentItem),1]);''它防止代碼編譯 - 你確定這是正確的嗎? – Bassie

+0

#Bassue - 這對我有用。在第一次運行時,我輸入一個較小的數字,然後進入if語句和錯誤消息。 – Cass

回答

0

發生這種情況,因爲DataGridTextColumn展示在正常模式下的TextBlockTextBox同時編輯。所以,當這個單元失去焦點時,DataGridTextColumn以正常模式返回,所以其內容將是TextBlock而不是TextBox,因此它顯示異常。

因此,儘量投入TextBlock而不是TextBox

0

您可以處理CellEditEnding事件。

背後

private void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
    DataGrid datagrid = sender as DataGrid; 
    if (e.EditAction == DataGridEditAction.Commit) 
    { 
     if (e.Column is DataGridBoundColumn) 
     { 
      DataGridBoundColumn column = (DataGridBoundColumn)e.Column; 
      if (column.Header.ToString() == "Size") 
      { 
       string oldValue = e.Row.DataContext.GetType().GetProperty("Size") 
            .GetValue(e.Row.DataContext).ToString(); 
       TextBox element = e.EditingElement as TextBox; 
       string newValue = element.Text; 
       int oldSize = int.Parse(oldValue); 
       int newSize = int.Parse(newValue); 
       if (newSize < oldSize) 
       { 
        string strMsg = "New size, " + newValue + ", is smaller then the original size, " 
            + oldValue + ".\nDue to potential data loss, this is not allowed."; 
        MessageBox.Show(strMsg); 
        element.Text = oldValue; 
        e.Cancel = true; 
       } 
      } 
     } 
    } 
} 

設置e.Cancel = true

<DataGrid AutoGenerateColumns="False" 
      CellEditEnding="DataGrid_CellEditEnding" 
      ... 
      > 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Size" Binding="{Binding Size, Mode=TwoWay}" .../> 

     ... 

    </DataGrid.Columns> 

    ... 

</DataGrid> 

代碼保持在編輯模式下的單元格。

+0

#bab7lon - 在字符串上失敗oldValue = e.Row.DataContext.GetType()。GetProperty(「Size」) .GetValue(e.Row.DataContext).ToString();它看起來.GetProperty(「大小」)返回null,我認爲 – Cass

+0

@Cass你怎麼填寫'數據網格'加載''?你是否將'ItemsSource'綁定到一個集合,使用'DataTable',...? – bab7lon

+0

是的我加載一個數據表的值,然後綁定到datagrid.ItemsSource,dtGrid.ItemsSource = dtGridData.DefaultView;我能夠解決這個錯誤,DataRowView drvRowView =(DataRowView)e.Row.DataContext; string oldValue = drvRowView.Row.ItemArray [1] .ToString(); – Cass

0

您正試圖將TextBlock投射到TextBox,這顯然不起作用。但如果你只是一味的總是轉換爲TextBlock這樣的:

System.Windows.Controls.TextBlock tbNewSize = (System.Windows.Controls.TextBlock)dtgCell.Content; 

...這將不能工作。這是因爲單元的Content可能是TextBox a TextBlock,這取決於單元當前是否處於編輯模式。

盡你所能的就是使用as運營商嘗試投射到一個TextBox如果轉換失敗,你再鑄造Content屬性設置爲TextBlock

private void DataGridCell_OnCellLostFocus(object sender, RoutedEventArgs e) 
{ 
    System.Windows.Controls.DataGridCell dtgCell = (System.Windows.Controls.DataGridCell)sender; 
    if (dtgCell.Column.Header.ToString() == "Size") 
    { 
     string text = null; 
     System.Windows.Controls.TextBox tbNewSize = dtgCell.Content as System.Windows.Controls.TextBox; 
     if (tbNewSize != null) 
     { 
      text = tbNewSize.Text; 
     } 
     else 
     { 
      System.Windows.Controls.TextBlock tb = dtgCell.Content as System.Windows.Controls.TextBlock; 
      if (tb != null) 
       text = tb.Text; 
     } 
     Int32 intNewSize = Convert.ToInt32(text); 
     Int32 intCurrSize = Convert.ToInt32(strFieldInfoOrig[dtGrid.Items.IndexOf(dtGrid.CurrentItem), 1]); 

     if (intNewSize < intCurrSize) 
     { 
      string strMsg; 

      strMsg = "New size, " + intNewSize.ToString() + " is smaller then the original size, " + intCurrSize.ToString(); 
      strMsg += Environment.NewLine; 
      strMsg += "Due to potential data loss, this is not allowed."; 
      System.Windows.MessageBox.Show(strMsg); 
      //dtgCell.Content = intCurrSize.ToString(); 
      dtgCell.Focus(); 
     } 
    } 
} 
+0

你試過這個嗎? – bab7lon

+0

#bab7lon - 我正在嘗試它,對於延遲抱歉,我的電腦崩潰,我現在剛剛恢復 – Cass

相關問題