1

我有以下 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 only办法via databindingwithout writing code behind)让行选择工作?

4

2 回答 2

0

似乎无法从 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}">

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

所以这里发生了什么。诀窍似乎是你必须等到数据网格建立它的内部容器模型。完成后,您可以选择一行并将其标记为选中。如果您尝试过早执行此操作,则没有行。

这确实应该是网格本身的属性。

于 2013-08-08T07:42:21.197 回答
0

使用来自NuGet的MVVM 灯的工作示例。

您可以在下部文本框中写入索引以查看它在 DataGrid 上的变化。

主窗口.xaml

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

主视图模型.cs

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

项目视图模型.cs

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;
        }
    }
}
于 2013-08-08T16:58:06.887 回答