2009-07-01 2 views
2

Я обновил DataGridRow в DataGrid Microsoft WPF ниже, проблема заключается в том, что пользователь нажимает на элементы границы шаблона строки (ов) не выбирайте. Есть ли способ сделать клик на границе причиной выбора строки.Граница в 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(); 
}