【问题标题】:update itemsource in codebehind not changing with xaml binding更新代码后面的数据源不随 xaml 绑定而改变
【发布时间】:2013-09-09 07:33:35
【问题描述】:

问题是我在运行时更改了项目的集合,我无法让组合框更新以显示新项目。我想通过 xaml 来实现。

我想为单个组合框解决此问题,然后也为作为 datagridComboBoxColumn 或作为包含作为数据模板的组合框的模板列的数据网格解决此问题。

我有这样的代码:

public class Member
{
    public string PublicID {get; set;}
    public string Description {get; set;}
}

public ObservableCollection<Member>  ComboBoxSource;

public UpdateComboBoxContents()
{
    List<Member> newList;

    // Omitted Code to retrieve list from datasource..

    ComboBoxSource = new ObservableCollection<Member>(newList);

    // If I uncomment the next line, combobox will show new contents:
    //myComboBox.itemssource = ComboBoxSource;

    // I’ve also tried..
    OnPropertyChanged("ComboBoxListSource");


}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string Name)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(Name));
    }
}

地点:

public partial class MyForm: UserControl, INotifyPropertyChanged

组合框 xaml 看起来像:

<ComboBox Name="myComboBox" SelectedValuePath="PublicID"
DisplayMemberPath="Description" ItemsSource="{Binding ComboBoxListSource,
UpdateSourceTrigger=PropertyChanged}"/>

我认为我搞砸了绑定或实现 INotifyPropertyChanged。在调试中,我注意到处理程序始终为 null,因此不会引发事件。

对于这个问题的第二部分(在数据网格中实现),我有:

public observableCollection<DatarowWithMember> ListDataRowWithMember;

// Code to populate list..
myDataGrid.Itemsource = ListDataRowWithMember

其中 DataRowWithMember 是一个实现 INotifyPropertyChanged 的​​类,并且有一个 MemberID 属性,该属性应该指向 Member 的 PublicID

我试过这个 xaml:

<DataGridTemplateColumn Header="Group" Width="*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding ComboBoxListSource, 
            RelativeSource={RelativeSource AncestorType=UserControl}}"
            SelectedValue="{Binding MemberID, UpdateSourceTrigger=PropertyChanged}"
            DisplayMemberPath="Description" 
            SelectedValuePath="PublicID" 
            IsHitTestVisible="False" SelectionChanged="ComboBoxChanged">
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>

<DataGridTemplateColumn.CellEditingTemplate>

        <DataTemplate>
            <ComboBox ItemsSource="{Binding ComboBoxListSource, 
                RelativeSource={RelativeSource AncestorType=UserControl}}" 
                DisplayMemberPath="Description" SelectedValuePath="PublicID"
                SelectedValue="{Binding MemberID,
                    UpdateSourceTrigger=PropertyChanged}"
                SelectionChanged="ComboBoxChanged"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

解决方案:正如其他人指出的那样,我在 ComboBoxSource 和 ComboBoxListSource 上有一个错字 - 这不是代码中的问题,而是我写出这个问题时的错误。

检查输出窗口确实显示了绑定问题,即找不到属性 ComboBoxSource。我改为:

private ObservableCollection<Member> _ComboBoxSource = new ObservableCollection<Member>()
public ObservableCollection<Member> ComboBoxSource
{
    get { return _ComboBoxSource; }
}

这很奏效。类属性与成员?

【问题讨论】:

  • 你是如何设置用户控件的 DataContext 的?如果实现 INotifyPropertyChanged 的​​类未设置为 DataContext 或未绑定到视图,则 Handler 为 null
  • 在输出窗口中的调试过程中是否出现绑定表达式错误?
  • 在我的控件初始化中,我有 DataContext = this;
  • 下次运行时会查找绑定表达式错误;我没有看输出窗口;我现在会的!

标签: c# wpf xaml binding combobox


【解决方案1】:

UpdateComboBoxContent 有两个问题导致了这个问题。

首先,您的属性称为ComboBoxSource,而在方法中,您调用的属性更改为“ComboBox List Source”。

其次,您根本不需要覆盖ObservableCollectionObservableCollection 可以自行通知绑定。如果您不能只更新更改的项目,请调用ComboBoxSource.Clear(),然后用新数据填充它,而不是覆盖它。

另外,永远不要设置myComboBox.itemssource = ComboBoxSource;,这样做会破坏你的绑定。如果您想使用后面的代码绑定属性,请参阅:http://msdn.microsoft.com/en-us/library/ms742863.aspx

【讨论】:

  • ComboBoxSource 和 ComboBoxListSource 是我对 SO 问题的错字,我应该直接复制和粘贴);但我会调查清楚并填充;并感谢您的链接;现在阅读。
  • 我已经用实际问题和解决方案更新了我的问题; Jordy van Eijk 为我指出了真正解决问题的正确方向;但由于链接和 clear() 的使用,我选择了这个作为正确答案
  • @andrew 谢谢,但您应该发布自己的答案并将其标记为问题的答案。您可以将答案投票为有帮助,但您应该只将真正的解决方案标记为答案。
【解决方案2】:

您似乎将属性名称 ComboBoxSource 和 PropertyCHanged 事件参数与绑定混合在一起。您应该在所有地方都使用与 ComboBoxSource 相同的名称,如下所示:

public ObservableCollection<Member>  ComboBoxSource;

public UpdateComboBoxContents()
{
    List<Member> newList;

    // Omitted Code to retrieve list from datasource..

    ComboBoxSource = new ObservableCollection<Member>(newList);        

    // I’ve also tried..
    OnPropertyChanged("ComboBoxSource");


}

<ComboBox Name="myComboBox" SelectedValuePath="PublicID"
DisplayMemberPath="Description" ItemsSource="{Binding ComboBoxSource,
UpdateSourceTrigger=PropertyChanged}"/>

【讨论】:

  • 感谢您发现这一点;我写出 SO 问题时的错误
猜你喜欢
  • 2012-11-20
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 2011-08-15
  • 1970-01-01
  • 2019-03-07
相关资源
最近更新 更多