如何使用MVVM应用程序在WPF中以编程方式设置DataGrid的选定项?

如何使用MVVM应用程序在WPF中以编程方式设置DataGrid的选定项?,wpf,mvvm,datagrid,datatable,Wpf,Mvvm,Datagrid,Datatable,我已将DataTable绑定到DataGrid控件。如何以编程方式设置所选项目 范例 在我的视图模型中,我有一个DataTable类型的属性来绑定DataGrid 私有数据表sizequalitytable; 公共数据表SizeQuantityTable { 得到 { 返回大小相等的表; } 设置 { sizeQuantityTable=值; NotifyPropertyChanged(“SizeQuantityTable”); } } 我的XAML 视图模型的构造函数(分配虚拟值) th

我已将
DataTable
绑定到
DataGrid
控件。如何以编程方式设置所选项目

范例

在我的视图模型中,我有一个DataTable类型的属性来绑定DataGrid

私有数据表sizequalitytable;
公共数据表SizeQuantityTable
{
得到
{
返回大小相等的表;
}
设置
{
sizeQuantityTable=值;
NotifyPropertyChanged(“SizeQuantityTable”);
}
}
我的
XAML


视图模型的构造函数(分配虚拟值)

this.SizeQuantityTable=newdatatable();
DataColumn sizeQuantityColumn=新DataColumn();
sizeQuantityColumn.ColumnName=“大小数量”;
this.SizeQuantityTable.Columns.Add(sizeQuantityColumn);
DataColumn sColumn=新DataColumn();
sColumn.ColumnName=“S”;
this.SizeQuantityTable.Columns.Add(sColumn);
DataColumn mColumn=新DataColumn();
mColumn.ColumnName=“M”;
this.SizeQuantityTable.Columns.Add(mColumn);
DataRow row1=this.SizeQuantityTable.NewRow();
第1行[sizeQuantityColumn]=“蓝色”;
行1[sColumn]=“12”;
第1行[mColumn]=“15”;
this.SizeQuantityTable.Rows.Add(第1行);
DataRow row2=this.SizeQuantityTable.NewRow();
第2行[sizeQuantityColumn]=“红色”;
第2行[sColumn]=“18”;
第2行[mColumn]=“21”;
this.SizeQuantityTable.Rows.Add(第2行);
DataRow row3=this.SizeQuantityTable.NewRow();
第3行[sizeQuantityColumn]=“绿色”;
第3行[sColumn]=“24”;
第3行[mColumn]=“27”;
this.SizeQuantityTable.Rows.Add(第3行);
嗯。我创建了三列,即
sizeQuantityColumn
scocolumn
mColumn
,并添加了三行,即
row1
row2

因此,假设我想将所选项目设置为
row2
(因此在视图中,第二行应该高亮显示)

我该怎么做

编辑

我将数据网格的
SelectedIndex
硬编码为1。(因此应选择第二行)。在
设计时间中
显示为选中状态。但不是在运行时。您可以在下面的快照中看到它

所以最后的问题是,没有突出显示该行


您可以始终使用
SelectedItem
属性并将其与行绑定,如下所示:

SelectedItem="{Binding ActiveRow}"
ViewModel
do中:

ActiveRow = secondRow;

有几种方法可以选择数据网格中的项目。这只取决于哪一个最适合这种情况

第一个也是最基本的是
SelectedIndex
这将只选择
DataGrid中该索引处的行

 <DataGrid SelectedIndex="{Binding SelectedIndex}" />

private int _selectedIndex;
public int SelectedIndex
{
    get { return _selectedIndex; }
    set { _selectedIndex = value; NotifyPropertyChanged("SelectedIndex"); }
}

SelectedIndex = 2;
最常见的是使用
SelectedValue
with
SelectedValuePath
set,在这种情况下,您可以设置要选择的列,然后通过设置相应的值来选择行

<DataGrid SelectedValuePath="Size Quantity" SelectedValue="{Binding SelectionValue}" 

private string _selectedValue
public string SelectionValue 
{
    get { return _selectedValue; }
    set { _selectedValue = value; NotifyPropertyChanged("SelectionValue"); }
}

SelectionValue = "Blue";
Xaml:


结果:


在数据网格中添加SelectedItem和SelectedValue

<DataGrid 
        ItemsSource="{Binding SizeQuantityTable}"
        AutoGenerateColumns="True" 
        SelectedValue ="{Binding SelectedValue}"
        Margin="0,0,0,120" />
    private ObservableCollection<Model> _itemSource
    public ObservableCollection<Model> ItemSource
    {
        get { return _itemSource; }
        set 
        { 
            _itemSource = value; 
            OnPropertyChanged("ItemSource"); 
        }
    }

    // Binding must be set to One-Way for read-only properties
    public int SelectedModelIndex
    {
        get 
        {
            if (ItemSource != null && ItemSource.Count > 0)
                return ItemSource.IndexOf(SelectedModel);
            else
                return -1;
        }            
    }

    private Model _selectedModel;
    public Model SelectedModel
    {
        get { return _selectedModel; }
        set 
        {
            _selectedModel = value;
            OnPropertyChanged("SelectedModel"); 
            OnPropertyChanged("SelectedModelIndex");               
        }                
    }

您也可以使用SelectedItem,这是首选。

我也遇到了同样的问题。 我看到datagrid的项在设计时被正确选择,但在运行时没有。(顺便说一下,我在xaml中创建了视图模型的实例)

我可以通过将代码从视图模型构造函数中以编程方式将所选项设置为视图模型中的另一个方法,然后在窗口(或usercontrol)的已加载事件中调用此方法来解决此问题

显然,在调用视图模型构造函数时,视图本身并没有完全完成初始化。 这可以通过不在视图模型构造函数中编码来避免

视图(xaml):

如果您不喜欢在代码隐藏中设置加载的
事件,也可以在xaml中设置(需要引用“Microsoft.Expression.Interactions”和“System.Windows.Interactivity”):


对于任何使用可观察集合的人,您可能会发现此解决方案很有用

SelectedModelIndex属性仅返回ItemSource集合中SelectedModel的索引。我发现设置SelectedIndex和SelectedItem会突出显示数据网格中的行

<DataGrid 
        ItemsSource="{Binding SizeQuantityTable}"
        AutoGenerateColumns="True" 
        SelectedValue ="{Binding SelectedValue}"
        Margin="0,0,0,120" />
    private ObservableCollection<Model> _itemSource
    public ObservableCollection<Model> ItemSource
    {
        get { return _itemSource; }
        set 
        { 
            _itemSource = value; 
            OnPropertyChanged("ItemSource"); 
        }
    }

    // Binding must be set to One-Way for read-only properties
    public int SelectedModelIndex
    {
        get 
        {
            if (ItemSource != null && ItemSource.Count > 0)
                return ItemSource.IndexOf(SelectedModel);
            else
                return -1;
        }            
    }

    private Model _selectedModel;
    public Model SelectedModel
    {
        get { return _selectedModel; }
        set 
        {
            _selectedModel = value;
            OnPropertyChanged("SelectedModel"); 
            OnPropertyChanged("SelectedModelIndex");               
        }                
    }
private observetecollection\u itemSource
公共可观测集合项源
{
获取{return\u itemSource;}
设置
{ 
_itemSource=值;
OnPropertyChanged(“ItemSource”);
}
}
//对于只读属性,必须将绑定设置为单向
公共int-SelectedModelIndex
{
得到
{
if(ItemSource!=null&&ItemSource.Count>0)
返回ItemSource.IndexOf(SelectedModel);
其他的
返回-1;
}            
}
私有模型_选择的模型;
公共模型选择模型
{
获取{return\u selectedModel;}
设置
{
_selectedModel=值;
OnPropertyChanged(“SelectedModel”);
OnPropertyChanged(“SelectedModelIndex”);
}                
}

我也尝试过这种方法。我定义了一个类型为
DataRowView
的属性,并绑定到DataGrid控件的
SelectedItem
属性。这样我就可以
获取所选项目。但是我
无法设置所选项目的程序。可能您忘记了使用双向绑定。SelectedItem=“{Binding ActiveRow,Mode=TwoWay}”怎么样?非常感谢。我已尝试绑定
SelectedItem
SelectedValue
属性。但我无法完成我的任务。然后按照您的建议,我尝试使用
SelectedIndex
。然后在设计时,它会显示它已被选中。但在运行时,它不会显示为选中状态。问题
private string _selectedValue;
public string SelectedValue
{
    get
    {
        return _selectedValue;
    }
    set
    {
        _selectedValue = value;
        NotifyPropertyChanged("SelectedValue");
    }
}

private DataTable sizeQuantityTable;
public DataTable SizeQuantityTable
{
    get
    {
        return sizeQuantityTable;
    }
    set
    {
        sizeQuantityTable = value;
        NotifyPropertyChanged("SizeQuantityTable");
    }
}
<Window x:Class="MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" 
        xmlns:viewModel="clr-namespace:ViewModels" Loaded="Window_Loaded">
    <Window.DataContext>
        <viewModel:ExampleViewModel/>
    </Window.DataContext>
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        ((ExampleViewModel)this.DataContext).LoadData();
    }
    <Window x:Class="MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" 
        xmlns:viewModel="clr-namespace:ViewModels">
    <Window.DataContext>
        <viewModel:ExampleViewModel/>
    </Window.DataContext>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <ei:CallMethodAction TargetObject="{Binding}" MethodName="LoadData"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
public class ExampleViewModel
{
    /// <summary>
    /// Constructor.
    /// </summary>
    public ExampleViewModel()
    {
        // Do NOT set selected item here
    }


    public void LoadData()
    {
        // Set selected item here
    }
    private ObservableCollection<Model> _itemSource
    public ObservableCollection<Model> ItemSource
    {
        get { return _itemSource; }
        set 
        { 
            _itemSource = value; 
            OnPropertyChanged("ItemSource"); 
        }
    }

    // Binding must be set to One-Way for read-only properties
    public int SelectedModelIndex
    {
        get 
        {
            if (ItemSource != null && ItemSource.Count > 0)
                return ItemSource.IndexOf(SelectedModel);
            else
                return -1;
        }            
    }

    private Model _selectedModel;
    public Model SelectedModel
    {
        get { return _selectedModel; }
        set 
        {
            _selectedModel = value;
            OnPropertyChanged("SelectedModel"); 
            OnPropertyChanged("SelectedModelIndex");               
        }                
    }