У меня есть DataGrid в приложении WPF, где я хочу разрешить пользователю выполнять действия над выбранным элементом в сетке. Я размещаю элементы управления для этих действий в DetailRow DataGrid.
Когда пользователь щелкает строку в сетке, я разворачиваю ее и открываю элементы управления. Когда они закончат, я бы хотел, чтобы они могли снова щелкнуть строку, чтобы скрыть эту строку сведений. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу заставить WPF различать щелчок по строке (фактически «заголовок» сведений о строке) и область сведений о строке, где находятся все мои элементы управления. Для WPF щелчок по детали означает щелчок по строке, и мой код считает это переключателем и поэтому скрывает строку.
Я делаю переключение в коде программной части, но я использую MVVM для приложения, поэтому, если бы я мог использовать более развязанный подход, мне было бы любопытно узнать. Вот пример кода:
ViewModel и модель:
namespace StackOverflow
{
public class ViewModel
{
public ObservableCollection<MyClass> MyCollection { get; set; }
public ViewModel()
{
MyCollection = new ObservableCollection<MyClass>
{
new MyClass(0, "Foo"),
new MyClass(1, "Bar")
};
}
}
public class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public MyClass(int id, string name)
{
Id = id;
Name = name;
}
}
}
Вид:
<Window x:Class="StackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackOverflow"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<local:ViewModel x:Key='MyVM'></local:ViewModel>
</Window.Resources>
<Grid DataContext='{StaticResource MyVM}'>
<DataGrid HorizontalAlignment='Center' Width='200' Margin='20'
RowDetailsVisibilityMode='Collapsed'
ItemsSource='{Binding MyCollection}'>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<EventSetter Event="UIElement.PreviewMouseLeftButtonDown"
Handler="OnRowLeftClicked" />
</Style>
</DataGrid.RowStyle>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Background='LightBlue' HorizontalAlignment='Center' Orientation='Horizontal' Height='100'>
<Button VerticalAlignment='Center'
HorizontalAlignment='Center'>Do stuff to this specific item</Button>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
Codebehind
namespace StackOverflow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private DataGridRow lastRowClicked;
public MainWindow()
{
InitializeComponent();
}
private void OnRowLeftClicked(object sender, RoutedEventArgs e)
{
var clickedRow = (DataGridRow)sender;
//If a Todo has been clicked before for this selected user, we need to decide whether a new Todo has been selected.
if (lastRowClicked != null)
{
//If the Todo that was clicked last time is the same as the one that was just clicked, toggle its visibility --- this is where problem lies
if (lastRowClicked == clickedRow)
{
if (clickedRow.DetailsVisibility == Visibility.Collapsed)
clickedRow.DetailsVisibility = Visibility.Visible;
else
clickedRow.DetailsVisibility = Visibility.Collapsed;
}
//If this Todo was not clicked last time, hide the last Todo and show this current one.
else
{
lastRowClicked.DetailsVisibility = Visibility.Collapsed;
clickedRow.DetailsVisibility = Visibility.Visible;
}
}
//If this is the first Todo that was clicked for this user, we can show it without collapsing another row.
else
{
clickedRow.DetailsVisibility = Visibility.Visible;
}
//in any case, save the currently clicked row for next time
lastRowClicked = clickedRow;
}
}
}
Обновлять:
Это было помечено как возможный дубликат для мне нужен шаблон Expand/Collapse для RowDetailsTemplate а>
Хотя это очень похожая проблема, решение в другом вопросе заключалось в использовании кнопки расширения в качестве столбца в сетке данных. Я бы предпочел просто щелкнуть в любом месте строку сетки данных и, в зависимости от того, была ли строка нажата ранее, развернуть или свернуть панель сведений. В качестве резервной копии я хотел бы, чтобы пользователь щелкнул левой кнопкой мыши, чтобы развернуть, и щелкнул правой кнопкой мыши, чтобы свернуть, что я сейчас и делаю в своем проекте.