2011-07-26 31 views
8

我已經研究了這一點,我很難過:我有一個WPF DataGrid,並使用MVVM模型。在某些情況下,我想要阻止在DataGrid中更改行的功能。我已經研究過這個,並嘗試了像here發現的技術。防止數據網格中的行更改

實際上,這是有效的,但有一個不理想的'閃爍'(它選擇點擊行,然後返回到先前的選擇),而這是一個接近的解決方案,我希望有一個更優雅的方式例如首先防止行更改。

我很驚訝沒有SelectionChanging或BeforeSelectionChanged,所以我可以從發射取消事件;強行阻止我的視圖模型中的索引更改似乎沒有任何區別。

我該怎麼做?

謝謝。

回答

5

如果您在某些情況下采取previewkeydownpreviewmousedown事件並只撥打e.Handled=true會發生什麼情況?

編輯: 滿足MVVM風格: 您可以創建一個BehaviorDependencyProperty您可以將您的情況結合。 在這種行爲中,您可以處理事件,也許還有其他一些東西,比如用戶點擊數據行或標題...

+0

以前的建議完美運行(雖然後者是一個非常有趣的建議,我也考慮過嘗試) - 謝謝。 – Mani5556

2

DispatcherPriority已設置爲ContextIdle。這會讓你閃爍,因爲你的SelectedItem被設置了兩次(並且它被渲染了兩次)。只需將優先級設置爲正常,並且不再閃爍。

+0

這幫了我,謝謝。 –

0

PreviewMouseDown方法here有一些示例。

一致意見是在DataGrid的SelectionChanged處理程序中將DataGrid.SelectedItem反轉回其原始值不能按預期工作;所有似乎都能正常工作的代碼示例通過要求分派器稍後安排來推遲逆轉。

你的數據網格上有CellStyle嗎?對我來說,以下工作:

XAML:

<DataGrid.CellStyle> 
    <Style TargetType="{x:Type DataGridCell}"> 
     <Style.Triggers> 
      <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="DarkSlateBlue"/> 
       <Setter Property="Foreground" Value="White"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</DataGrid.CellStyle> 

代碼隱藏:

private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (e.AddedItems.Count > 0) 
    { 
     object x = e.AddedItems[0]; 
     if (x is MyObjectType && x != myViewModel.CurrentItem && 
      myViewModel.ShouldNotDeselectCurrentItem()) 
     { 
      // this will actually revert the SelectedItem correctly, but it won't highlight the correct (old) row. 
      this.MyDataGrid.SelectedItem = null; 
      this.MyDataGrid.SelectedItem = myViewModel.CurrentItem; 
     } 
    } 
} 

的一點是,SelectedCellsChanged事件SelectionChanged事件解僱後 - 特別是,在設定SelectedItem沒有正確更新SelectedCells,它是隻讀屬性,所以更多的代碼隱藏:

private void MyDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) 
{ 
    List<DataGridCellInfo> selectedCells = MyDataGrid.SelectedCells.ToList(); 

    List<MyObjectType> wrongObjects = selectedCells.Select(cellInfo => cellInfo.Item as MyObjectType) 
     .Where (myObject => myObject != myViewModel.CurrentItem).Distinct().ToList(); 
    if (wrongObjects.Count > 0) 
    { 
     MyDataGrid.UnselectAllCells(); 
     MyDataGrid.SelectedItem = null; 
     MyDataGrid.SelectedItem = myViewModel.CurrentItem; 
    } 
} 

顯然,處理程序需要連接到數據網格上的相應事件。

這可以像預期的那樣工作,如果需要可以正確取消選擇更改,並且不會產生閃爍。

相關問題