C# 如何使用仅XAML数据绑定使用DataGrid进行行选择
我有以下DataGrid定义C# 如何使用仅XAML数据绑定使用DataGrid进行行选择,c#,wpf,datagrid,C#,Wpf,Datagrid,我有以下DataGrid定义 <DataGrid VirtualizingPanel.VirtualizationMode="Recycling" CanUserAddRows="False" CanUserDeleteRows="False" SelectionMode="Single" ItemsSource="{Binding ToolPath.ToolPath, Mode=OneWay,
<DataGrid
VirtualizingPanel.VirtualizationMode="Recycling"
CanUserAddRows="False"
CanUserDeleteRows="False"
SelectionMode="Single"
ItemsSource="{Binding
ToolPath.ToolPath,
Mode=OneWay,
Converter={StaticResource indexedConverter}}"
AutoGenerateColumns="False"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
我使用的是MVVM,有一个视图模型,它具有SelectedIndex属性,实现了INPC。我使用snoop来验证DataGrid上的SelectedIndex在视图模型中发生更改时是否发生了更改。但是,执行此操作时,栅格的行未被选中或高亮显示
正如您所看到的,该行没有高亮显示,但我想我可以检测到该行左侧3像素宽的小部件是深蓝色的
是否有一种XAML唯一的方法,通过数据绑定而不编写代码来进行行选择?似乎无法从XAML中找到一种方法。通过大量的黑客攻击和阅读帖子,我能想到的最好的方法就是
<DataGrid
x:Name="ToolPathGridView"
VirtualizingPanel.VirtualizationMode="Recycling"
CanUserAddRows="False"
SelectionUnit="FullRow"
CanUserDeleteRows="False"
SelectionMode="Single"
Loaded="ToolPathGridView_Loaded"
ItemsSource="{Binding
ToolPath.ToolPath,
Mode=OneWay,
Converter={StaticResource indexedConverter}}"
AutoGenerateColumns="False"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
那么这里发生了什么。诀窍似乎是您必须等到datagrid构建了它的内部容器模型。完成后,您可以拾取一行并将其标记为选中。如果您太早尝试执行此操作,则不会出现行
这实际上应该是网格本身的属性。使用from的工作示例
您可以在下面的文本框中写入索引,以查看它在DataGrid上的变化
MainWindow.xaml
你能粘贴IndexedConverter的代码吗?为什么不绑定到集合并使用SelectedItem?
private void ToolPathGridView_Loaded( object sender, RoutedEventArgs e )
{
ToolPathGridView.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
}
void ItemContainerGenerator_StatusChanged( object sender, EventArgs e )
{
if ( ToolPathGridView.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated )
{
int i = 0;
if ( ViewModel!=null )
{
i = ViewModel.SelectedIndex;
}
ToolPathGridView.SelectedIndex = 0;
DataGridRow r = ToolPathGridView.ItemContainerGenerator.ContainerFromIndex(0) as DataGridRow;
if ( r != null )
{
r.IsSelected = false;
r.IsSelected = true;
}
}
}
<Window
x:Class="Test_DataGridSelectedIndexItem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:testDataGridSelectedIndexItem="clr-namespace:Test_DataGridSelectedIndexItem"
Title="MainWindow"
Height="350"
Width="525"
>
<Window.DataContext>
<testDataGridSelectedIndexItem:MainViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=".9*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid
Grid.Row="0"
ItemsSource="{Binding Items}"
SelectedItem="{Binding Selected, Mode=TwoWay}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
/>
<TextBlock
Grid.Row="1"
Text="{Binding Selected}"
/>
<TextBlock
Grid.Row="2"
Text="{Binding SelectedIndex}"
/>
<TextBox
Grid.Row="3"
Text="{Binding SelectedIndex, Mode=TwoWay}"
/>
</Grid>
</Window>
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight;
namespace Test_DataGridSelectedIndexItem
{
public class MainViewModel : ViewModelBase
{
private ItemViewMode selected;
private int selectedIndex;
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewMode>()
{
new ItemViewMode("Item1"),
new ItemViewMode("Item2"),
new ItemViewMode("Item3"),
};
}
public ObservableCollection<ItemViewMode> Items { get; private set; }
public ItemViewMode Selected
{
get
{
return this.selected;
}
set
{
this.selected = value;
this.RaisePropertyChanged(() => this.Selected);
}
}
public int SelectedIndex
{
get
{
return this.selectedIndex;
}
set
{
this.selectedIndex = value;
this.RaisePropertyChanged(() => this.SelectedIndex);
}
}
}
}
using GalaSoft.MvvmLight;
namespace Test_DataGridSelectedIndexItem
{
public class ItemViewModel : ViewModelBase
{
private string text;
public ItemViewModel() : this(string.Empty)
{
}
public ItemViewModel(string text)
{
this.text = text;
}
public string Text
{
get
{
return this.text;
}
set
{
this.text = value;
this.RaisePropertyChanged(() => this.Text);
}
}
public override string ToString()
{
return this.text;
}
}
}