2009-07-01 25 views
2

Microsoft WPF DataGridのDataGridRowを以下にretemplatedしました。ユーザーがテンプレートの境界要素をクリックすると問題が発生します。選択されません。境界線をクリックして行を選択させる方法はありますか?ControlTemplateのボーダーがDataGridで奇数選択動作を引き起こす

<Grid x:Name="LayoutRoot" Margin="0,0,0,-1"> 
     <Border x:Name="DGR_Border" BorderBrush="Transparent" Background="Transparent" BorderThickness="1" CornerRadius="5" SnapsToDevicePixels="True"> 
      <Border x:Name="DGR_InnerBorder" BorderBrush="Transparent" Background="Transparent" BorderThickness="1" CornerRadius="5" SnapsToDevicePixels="True"> 
       <toolkit:SelectiveScrollingGrid Name="DGR_SelectiveScrollingGrid"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
        </Grid.ColumnDefinitions> 

        <Grid.RowDefinitions> 
         <RowDefinition Height="*"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 

        <toolkit:DataGridCellsPresenter Grid.Column="1" Name="DGR_CellsPresenter" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
        <toolkit:DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" Visibility="{TemplateBinding DetailsVisibility}" toolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static Controls:DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static Controls:SelectiveScrollingOrientation.Vertical}}" /> 
        <toolkit:DataGridRowHeader Grid.RowSpan="2" toolkit:SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Controls:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Controls:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Controls:DataGridHeadersVisibility.Row}}"/> 
       </toolkit:SelectiveScrollingGrid> 
      </Border> 
     </Border> 
    </Grid> 

答えて

2

内部メソッドの呼び出しはやや危険です。実装の詳細が変更されたらどうなりますか?以前のバージョンには多くの変更がありました。

protected void DataGridRow_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    // GetVisualChild<T> helper method, simple to implement 
    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer); 

    // try to get the first cell in a row 
    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(0); 
    if (cell != null) 
    { 
     RoutedEventArgs newEventArgs = new RoutedEventArgs(MouseLeftButtonDownEvent); 
     //if the DataGridSelectionUnit is set to FullRow this will have the desired effect 
     cell.RaiseEvent(newEventArgs); 
    } 
} 

これはセル自体をクリックするのと同じ効果を持つことになり、そして唯一のパブリックメンバを使用します。

は、私は単にあなたの行に、このようなイベントハンドラを追加するために、それはより賢明かもしれないと思いますDataGrid要素。

+0

素晴らしい、ありがとう! – dariusriggins

1

ツールキットDataGridRowには、定義済みのOnMouseDownオーバーライドまたは同様のメソッドはありません。

internal void HandleSelectionForCellInput(DataGridCell cell, bool startDragging, bool allowsExtendSelect, bool allowsMinimalSelect) 
{ 
    DataGridSelectionUnit selectionUnit = SelectionUnit; 

    // If the mode is None, then no selection will occur 
    if (selectionUnit == DataGridSelectionUnit.FullRow) 
    { 
     // In FullRow mode, items are selected 
     MakeFullRowSelection(cell.RowDataItem, allowsExtendSelect, allowsMinimalSelect); 
    } 
    else 
    { 
     // In the other modes, cells can be individually selected 
     MakeCellSelection(new DataGridCellInfo(cell), allowsExtendSelect, allowsMinimalSelect); 
    } 

    if (startDragging) 
    { 
     BeginDragging(); 
    } 
} 

入力セルに発生した場合、このメソッドが呼び出されるフル行の選択は、トラフこの方法扱われます。 MakeFullRowSelectionメソッドは、行内のすべてのセルのみを選択し、行自体は選択しません。

したがって、DataGridRow(DataGridCellではなく)をクリックすると、マウスの操作や選択処理が行われません。必要なものを達成するには、IsSelectedプロパティを設定する行のマウスダウンイベントに、ある種のマウスダウンハンドラを追加する必要があります。もちろん、row.IsSelectedはそれを暗示または設定しないので、行の各セルに対して選択したプロパティを個別に指定する必要があります。

0

私は一般的なアイデアを得ましたが、IsSelectedをtrueに設定すると予想通りに動作しませんでした。ヒットすると、行が選択されますが、他の行は選択解除されません。必要な場合)。ハンドラでHandleSelectionForCellInputを呼び出すことで問題を回避することができました。次に、グリッドとセルで作成されたラムダを完全に呼び出すようにします。

public static Action<DataGrid, DataGridCell, bool> CreateSelectRowMethod(bool allowExtendSelect, bool allowMinimalSelect) 
{ 
var selectCellMethod = typeof(DataGrid).GetMethod("HandleSelectionForCellInput", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 

ParameterExpression dataGrid = Expression.Parameter(typeof(DataGrid), "dataGrid"); 
ParameterExpression paramCell = Expression.Parameter(typeof(DataGridCell), "cell"); 
ParameterExpression paramStartDragging = Expression.Parameter(typeof(bool), "startDragging"); 
var paramAllowsExtendSelect = Expression.Constant(allowExtendSelect, typeof(bool)); 
var paramAllowsMinimalSelect = Expression.Constant(allowMinimalSelect, typeof(bool)); 

var call = Expression.Call(dataGrid, selectCellMethod, paramCell, paramStartDragging, paramAllowsExtendSelect, paramAllowsMinimalSelect); 

return (Action<DataGrid, DataGridCell, bool>)Expression.Lambda(call, dataGrid, paramCell, paramStartDragging).Compile(); 
} 
関連する問題