WPF Xaml GridView SelectionChanged行为

WPF Xaml GridView SelectionChanged行为,wpf,xaml,mvvm,prism,Wpf,Xaml,Mvvm,Prism,我正在使用Prism.MVVM的WPF视图,它允许我们的用户编辑记录。 最初,要编辑的记录是通过组合框选择的 <ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Records}" SelectedItem="{Binding SelectedRecord}"/> 这是通过SelectedItem绑定模式的各种选项尝试的。

我正在使用Prism.MVVM的WPF视图,它允许我们的用户编辑记录。 最初,要编辑的记录是通过组合框选择的

<ComboBox IsSynchronizedWithCurrentItem="True" 
          ItemsSource="{Binding Records}"                 
          SelectedItem="{Binding SelectedRecord}"/>
这是通过
SelectedItem
绑定模式的各种选项尝试的。 如果DataGrid
SelectedItem
绑定被删除,我们将得到1、2、4、5、6和7。但是,从组合框中选择记录不会在网格中显示所选的记录

如果DataGrid
SelectedItem
绑定设置为单向,则通过组合框选择记录将中断:设置
SelectedRecord
将触发DataGrid中的SelectionChanged事件,该事件使用事件之前的值,并有效地将所有内容设置回原始值

这可以通过在ViewModel中的属性集上引入sentinal来解决

Private\u选择记录作为记录类型
Private _enableRecordSelection为布尔值=true
公共属性选择Record作为记录类型
得到
Return\u selectedRecord
结束
设置(值为记录类型)
如果启用记录选择
_enableRecordSelection=false
SetProperty(_selectedRecord,value)
_enableRecordSelection=true
如果结束
端集
端属性
这实际上是可行的,我们在写问题的时候就想到了,但感觉很糟糕。我的直觉告诉我必须有更好的方法,所以我仍然在问:

是否有一种干净(最好是仅限xaml)的方法来设置此设置

我们尝试过的其他最成功的事情: 具有双向绑定的DataGrid的直接xaml配置

<DataGrid x:Name="TheDataGrid"
          ItemsSource="{Binding Source={StaticResource GridRecords}}"
          SelectedItem="DataContext.SelectedRecord, ElementName=LayoutRoot, Mode=TwoWay}"/>

这样,我们就满足了要求1到6;但是,当通过网格选择记录时,总是突出显示上一条记录,而不是当前记录

DataGrid.InputBindings

<DataGrid.InputBindings>
    <MouseBinding Gesture="LeftClick"
                  CommandParameter="{Binding SelectedItem, ElementName=TheDataGrid}"
                  Command="{Binding DataContext.SelectRecordFromGridCommand, ElementName=LayoutRoot}"/>
</DataGrid.InputBindings>

如果没有
SelectedItem
绑定,则其行为类似于
SelectionChanged
上的无绑定
InteractionTrigger
,只是它需要用户执行多个鼠标操作。第一次单击将选择网格中的行(实际的蓝色粗体选择),第二次单击将触发该命令

SelectedItem
上使用
单向
绑定时,其行为类似于直接的xaml配置,只是需要多次单击

再次重申这个问题:
有没有比使用属性设置器上的sentinal值更干净的方法来完成7项要求?

根据您的询问,我知道您希望同步Datagrid和ComboBox中的选定项。如果我是您,我将使用绑定同一对象的两个控件(SelectedRecord)。我只熟悉C语言,所以代码是用C语言编写的。希望它能帮助你

对于XAML:

<DataGrid ItemsSource="{Binding Records}"
          SelectedValue="{Binding SelectedRecord}" />
<ComboBox Grid.Column="1" ItemsSource="{Binding Records}"
          DisplayMemberPath="Id"
          SelectedValue="{Binding SelectedRecord}" />
public ObservableCollection<Record> Records { get; } = new ObservableCollection<Record>();

public Record SelectedRecord
{
    get { return _selectedRecord; }
    set
    {
        _selectedRecord = value;
        OnPropertyChanged();
    }
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public class Record
{
    private static int id = 0;
    public Record()
    {
        Id = ++id;
    }

    public int Id { get; set; }
}

对于ViewModel:

<DataGrid ItemsSource="{Binding Records}"
          SelectedValue="{Binding SelectedRecord}" />
<ComboBox Grid.Column="1" ItemsSource="{Binding Records}"
          DisplayMemberPath="Id"
          SelectedValue="{Binding SelectedRecord}" />
public ObservableCollection<Record> Records { get; } = new ObservableCollection<Record>();

public Record SelectedRecord
{
    get { return _selectedRecord; }
    set
    {
        _selectedRecord = value;
        OnPropertyChanged();
    }
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public class Record
{
    private static int id = 0;
    public Record()
    {
        Id = ++id;
    }

    public int Id { get; set; }
}
公共ObservableCollection记录{get;}=new ObservableCollection(); 公共记录选择记录 { 获取{return\u selectedRecord;} 设置 { _selectedRecord=值; OnPropertyChanged(); } } 公共事件属性更改事件处理程序属性更改; [NotifyPropertyChangedInvocator] 受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null) { PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName)); } 公开课记录 { 私有静态int id=0; 公共记录() { Id=++Id; } 公共int Id{get;set;} }
根据您的询问,我知道您希望同步Datagrid和ComboBox中的选定项。如果我是您,我将使用绑定同一对象的两个控件(SelectedRecord)。我只熟悉C语言,所以代码是用C语言编写的。希望它能帮助你

对于XAML:

<DataGrid ItemsSource="{Binding Records}"
          SelectedValue="{Binding SelectedRecord}" />
<ComboBox Grid.Column="1" ItemsSource="{Binding Records}"
          DisplayMemberPath="Id"
          SelectedValue="{Binding SelectedRecord}" />
public ObservableCollection<Record> Records { get; } = new ObservableCollection<Record>();

public Record SelectedRecord
{
    get { return _selectedRecord; }
    set
    {
        _selectedRecord = value;
        OnPropertyChanged();
    }
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public class Record
{
    private static int id = 0;
    public Record()
    {
        Id = ++id;
    }

    public int Id { get; set; }
}

对于ViewModel:

<DataGrid ItemsSource="{Binding Records}"
          SelectedValue="{Binding SelectedRecord}" />
<ComboBox Grid.Column="1" ItemsSource="{Binding Records}"
          DisplayMemberPath="Id"
          SelectedValue="{Binding SelectedRecord}" />
public ObservableCollection<Record> Records { get; } = new ObservableCollection<Record>();

public Record SelectedRecord
{
    get { return _selectedRecord; }
    set
    {
        _selectedRecord = value;
        OnPropertyChanged();
    }
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public class Record
{
    private static int id = 0;
    public Record()
    {
        Id = ++id;
    }

    public int Id { get; set; }
}
公共ObservableCollection记录{get;}=new ObservableCollection(); 公共记录选择记录 { 获取{return\u selectedRecord;} 设置 { _selectedRecord=值; OnPropertyChanged(); } } 公共事件属性更改事件处理程序属性更改; [NotifyPropertyChangedInvocator] 受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null) { PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName)); } 公开课记录 { 私有静态int id=0; 公共记录() { Id=++Id; } 公共int Id{get;set;} }
感谢您让我注意到SelectedValue,但是这与我所问的带有双向绑定的DataGrid的直接xaml配置部分的行为相同。从网格中选择记录时,显示为选中的行始终落后于单击一次。如果最初选择了Z,我单击Y,Z仍显示为网格中的选定项,页面上的其他所有位置都将更新为Y。如果我单击X,Y显示为网格中的选定项,页面上的其他所有位置都将更新为X。。@Mr.Mindor,我认为双向绑定不应成为导致所选延迟问题的原因。是否使用其他触发器或命令影响它?在我的测试中,我无法重现您的问题。感谢您提醒我注意SelectedValue,但是这与我问题中带有双向绑定的DataGrid的直接xaml配置部分的行为相同。从网格中选择记录时,显示为选中的行始终落后于单击一次。如果最初选择了Z,我单击Y,Z仍显示为网格中的选定项,页面上的其他所有位置都将更新为Y。如果我单击X,Y显示为网格中的选定项,页面上的其他所有位置都将更新为X。@Mr.Mindor,我认为双向绑定不应该是原因