9

私はこれを調査しましたが、困惑しています.WPF DataGridがあり、MVVMモデルを使用しています。特定の状況下で、DataGrid の行を変更できないようにしたいと考えています。私はこれを調査し、ここにあるような手法を試しました。

実際には、これは機能しますが、望ましくない「ちらつき」があります (クリックされた行を一瞬選択してから前の選択に戻ります)。そもそも行の変更。

SelectionChanging または BeforeSelectionChanged がないことに驚いたので、イベントの発生をキャンセルできました。ビューモデルでインデックスの変更を強制的に防止しても、違いはないようです。

これどうやってするの?

ありがとうございました。

4

3 に答える 3

6

previewkeydownandイベントを使用して、特定の状況でpreviewmousedown単に呼び出すとどうなりますか?e.Handled=true

編集: mvvm スタイルを満たすために:状況をバインドできるaBehaviorで aを作成できます。DependencyPropertyこの動作では、ユーザーがデータ行またはヘッダーをクリックするなど、イベントやその他のものを処理できます...

于 2011-07-26T05:45:55.133 に答える
2

DispatcherPriorityはContextIdleに設定されています。これにより、SelectedItemが2回設定されている(そして2回レンダリングされている)ため、ちらつきが発生します。優先度を通常に設定するだけで、ちらつきがなくなります。

于 2012-01-11T09:55:16.340 に答える
0

ここに PreviewMouseDown メソッドの例がいくつかあります。

一般的な合意は、データグリッドの 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;
    }
}

明らかに、ハンドラーは、データ グリッド上の対応するイベントに接続する必要があります。

これは期待どおりに機能し、必要に応じて選択の変更を適切にキャンセルし、ちらつきも発生しませんでした。

于 2013-09-24T04:55:06.183 に答える