更新后面的代码中的itemssource不会随xaml绑定而改变

时间:2013-09-09 07:33:36

标签: c# wpf xaml binding combobox

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

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

我的代码如下:

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

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

这很有效。 class Properties vs members?

2 个答案:

答案 0 :(得分:1)

UpdateComboBoxContent导致这两个问题。

首先,您的属性名为ComboBoxSource,而在该方法中,您使用“ComboBox 列表来源”调用属性更改。

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

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

答案 1 :(得分:0)

从您看来,您将属性名称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}"/>