Я обновил DataGridRow в Microsoft WPF 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>
Вызов внутреннего метода кажется несколько опасным. Что делать, если детали реализации меняются? В предыдущих версиях было много изменений.
Я думаю, что может быть более разумным просто добавить обработчик событий, подобный этому, в ваши строки:
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.
Инструментарий 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. Разумеется, обратите внимание, что вы должны указывать выбранное свойство для каждой ячейки в строке по отдельности, так как строка .IsSelected не подразумевает или не устанавливает это.
Спасибо за ответ, я получил общую идею, однако установка 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();
}