Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用仅XAML数据绑定使用DataGrid进行行选择_C#_Wpf_Datagrid - Fatal编程技术网

C# 如何使用仅XAML数据绑定使用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定义

 <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;
        }
    }
}