【问题标题】:DataBinding not working for Combobox in DataGridDataBinding 不适用于 DataGrid 中的 Combobox
【发布时间】:2016-04-13 09:21:43
【问题描述】:

这个快把我逼疯了……

这是我用来绑定数据网格中列中的组合框的 xaml。 ItemSource 指向持有“Pipetter”类的 ObservableCollection。 CellTemplate,只需要显示当前选中行的这个 Pipetter 类的“name”属性。

问题是,一旦我在组合框中选择了一个值,所选择的值就会突然出现在该列的所有行中。我已经以许多不同的方式重新设计了这些方法,并且在每种情况下都发生了这种情况。关于关闭什么设置的任何想法?

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <ComboBox 
            IsEditable="False"  
            ItemsSource="{Binding DataContext.Pipettors, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Mode=TwoWay}"
            SelectedItem="{Binding DataContext.SelectedPipettor, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
            SelectedValue="{Binding TipGroup.PipettorTipType.Pipettor}"
            DisplayMemberPath="Name"
            />
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Label 
            Content="{Binding TipGroup.PipettorTipType.Pipettor.Name}" 
            Style="{DynamicResource DataGridRowLabel}" 
            />
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

这是选定项绑定到的 Vm 中的属性。我只是将“SelectedItem”分配给当前选定行(SelectedTipGroup)中的相应属性。这在 DataGrid 定义中被定义为“SelectedItem”。

 private Pipettor selectedPipettor;
    public Pipettor SelectedPipettor
    {

        get { return selectedPipettor; }
        set
        {
            SetProperty(ref selectedPipettor, value);
            SelectedTipGroup.TipGroup.PipettorTipType.Pipettor = value;
        }
    }

我按照建议更新了组合框绑定:

<DataGridTemplateColumn.CellEditingTemplate>
      <DataTemplate>
          <ComboBox x:Name="PipetterComboBox"
              ItemsSource= "{Binding DataContext.Pipettors, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=TwoWay}"
                                  SelectedItem="{Binding TipGroup.PipettorTipType.Pipettor}" IsSynchronizedWithCurrentItem="True"
                                  DisplayMemberPath="Name"
                                 />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>

                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Content="{Binding TipGroup.PipettorTipType.Pipettor.Name}" Style="{DynamicResource DataGridRowLabel}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

当在数据网格的一行中进行选择时,相同的值出现在该列的所有行中......它只是试图将 selectedItem 类分配给当前行中的类属性“Pipettor”。 ..

在这个上花了 DAYS 天.. 没有意义...

谢谢!

这是组合框绑定到的属性。组合框的 ItemsSource 只是 Pipettor 类型的 observablecollection。

  private Pipettor pipettor;
    [DataMember]
    public Pipettor Pipettor
    {
        get { return this.pipettor; }
        set
        {
            if (SetProperty(ref this.pipettor, value))
            {
                //***BKM This was failing on delete - not sure if masking or not but will null check
                //note something similar in other models - review
                if (value != null)
                {
                    this.pipettorId = this.pipettor.Identity;

                }
            }
        }
    }

和 SetProperty()

 protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(field, value)) 
        { 
            return false; 
        }

        field = value;
        //Check to make sure Tracking is Initialized but no need to do anything
        if (!this.Tracking.Initialized)
        {

        }

        RaisePropertyChanged(propertyName);
        return true;
    }

【问题讨论】:

  • 也许在你的属性设置器中通知 IPropertyChanged?
  • SetProperty 是做什么的? PropertyChanged 有没有机会被解雇?
  • setproperty 只是封装了检查以查看新值是否为 != 当前值,如果是,则引发 propertyChanged 事件并将支持字段设置为新值。

标签: wpf data-binding wpfdatagrid


【解决方案1】:

ComboBox 的 SelectedItem 正在使用 RelativeSource 来使用 DataGrid 的 DataContext,因此所有行都使用相同的 SelectedItem。将此更改为 DataGrid 中每一行的项中的绑定。看起来您可能已经在 SelectedValue 上拥有此绑定,看起来它确实应该在 SelectedItem 上。

SelectedValue 绑定无法按原样工作,因为未设置 SelectedValuePath。有关 SelectedItem 和 SelectedValue 之间的区别,请参阅此问题: Difference between SelectedItem, SelectedValue and SelectedValuePath

编辑:根据此答案更新问题后,IsSynchronizedWithCurrentItem="True" 已添加到组合框的 xaml 中。来自 MSDN 的有关此属性的文档:

"您可以将 IsSynchronizedWithCurrentItem 属性设置为 true,以确保选中的项始终对应于 ItemCollection 中的 CurrentItem 属性。例如,假设有两个 ListBox 控件的 ItemsSource 属性设置为相同的源。设置 IsSynchronizedWithCurrentItem在两个列表框中设置为 true,以确保每个 ListBox 中的选定项相同。"

将此设置为 true 这也会导致所有 ComboBox 使用相同的选择。从 ComboBox 的 xaml 中删除此属性。

MSDN 参考:https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.issynchronizedwithcurrentitem(v=vs.110).aspx

【讨论】:

  • 我试过这样做,当我选择一个下拉值时,它仍在更新所有行:请参阅编辑...
  • 您要绑定的 TipGroup.PipettorTipType.Pipettor 的代码是什么样的?
  • 您在更新的 xaml 中添加了 IsSynchronizedWithCurrentItem="True"。这旨在将具有相同 ItemsSource 的多个选择同步到相同的 SelectedItem。删除它。
  • 好的。如果您已将其删除,那么此时我认为问题不再存在于您的 xaml 中,并且我在您共享的其他代码中看不到任何问题。您应该尝试通过调试来确定是什么导致 Pipettor 属性在其他行中发生变化。
  • 是的,经过更多挖掘,似乎原因是这些模型类使用了一个基类,该基类是为实现 EntityFramework 的跟踪而创建的。当我创建另一个没有继承自内部创建的 EF 基类的类时,它运行良好!我花了很多时间在这上面,我还没有找到确切的原因。我必须继续使用新的班级结构......到目前为止效果很好......谢谢!
猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
相关资源
最近更新 更多