简体   繁体   English

ComboBox WPF绑定列表已更改

[英]ComboBox wpf binding list changed

I have a question about ComboBox regarding binding selected item on reloading list. 我有一个关于ComboBox的问题,关于绑定重新加载列表中的选定项目。

class Model : ViewModelBase
{
    /// <summary>
    /// The <see cref="Title" /> property's name.
    /// </summary>
    public const string TitlePropertyName = "Title";

    private string _title = "";

    /// <summary>
    /// Sets and gets the Title property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public string Title
    {
        get
        {
            return _title;
        }

        set
        {
            if (_title == value)
            {
                return;
            }

            RaisePropertyChanging(TitlePropertyName);
            _title = value;
            RaisePropertyChanged(TitlePropertyName);
        }
    }

    /// <summary>
    /// The <see cref="Id" /> property's name.
    /// </summary>
    public const string idPropertyName = "Id";

    private int _myId = 0;

    /// <summary>
    /// Sets and gets the id property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public int Id
    {
        get
        {
            return _myId;
        }

        set
        {
            if (_myId == value)
            {
                return;
            }

            RaisePropertyChanging(idPropertyName);
            _myId = value;
            RaisePropertyChanged(idPropertyName);
        }
    }
}

Binded ViewModel: 绑定的ViewModel:

class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {

        PopulateCommand = new RelayCommand(() =>
        {
            Populate();
        });

        SetCommand = new RelayCommand(() =>
        {
            Id = 3;
        });
    }

    public void Populate()
    {
        MyList = new ObservableCollection<Model>(){
            new Model(){
                Id = 1,
                Title = "numer1"
            },
            new Model(){
                Id = 2,
                Title = "numer2"
            },
            new Model(){
                Id = 3,
                Title = "numer3"
            },
            new Model(){
                Id = 4,
                Title = "numer4"
            },
        };
    }

    public RelayCommand PopulateCommand { get; private set; }
    public RelayCommand SetCommand { get; private set; }

    /// <summary>
    /// The <see cref="MyList" /> property's name.
    /// </summary>
    public const string MyListPropertyName = "MyList";

    private ObservableCollection<Model> _myList = null;

    /// <summary>
    /// Sets and gets the MyList property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public ObservableCollection<Model> MyList
    {
        get
        {
            return _myList;
        }

        set
        {
            if (_myList == value)
            {
                return;
            }

            RaisePropertyChanging(MyListPropertyName);
            _myList = value;
            RaisePropertyChanged(MyListPropertyName);
        }
    }

    /// <summary>
    /// The <see cref="Id" /> property's name.
    /// </summary>
    public const string IdPropertyName = "Id";

    private int _id = 0;

    /// <summary>
    /// Sets and gets the Id property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public int Id
    {
        get
        {
            return _id;
        }

        set
        {
            if (_id == value)
            {
                return;
            }

            RaisePropertyChanging(IdPropertyName);
            _id = value;
            RaisePropertyChanged(IdPropertyName);
        }
    }

}

xaml: XAML:

    <ComboBox
            ItemsSource="{Binding MyList}"
            DisplayMemberPath="Title" SelectedValue="{Binding Id, Mode=TwoWay}" SelectedValuePath="Id" IsSynchronizedWithCurrentItem="True"/>
    <Button Content="Populate"
            Command="{Binding PopulateCommand}" />
    <Button Content="Set"
            Command="{Binding SetCommand}" />

    <TextBlock Text="{Binding Id}" Width="100"/>

So, populateButton is creating List for combobox binding, setButton sets the id for 3. Then if I populate list again choosen Id in combobox is 1. Shouldn't it be still 3? 因此,populateButton正在为组合框绑定创建List,setButton将id设置为3。然后,如果我再次填充列表,则选择combobox中的Id为1。是否应该仍然为3? I mean, shouldn't the combobox set Selected Item for model where id=3. 我的意思是,组合框不应为id = 3的模型设置“选定项”。

I also tried without IsSynchronizedWithCurrentItem set to true. 我还尝试了将IsSynchronizedWithCurrentItem设置为true的情况。 Then after reloading the list there is nothing selected in combobox. 然后,在重新加载列表后,组合框中没有任何选择。 Is there a way to synchronize selectedItem with Id? 有没有一种方法可以将selectedItem与ID同步?

Seems like the list should be initialized first, then I should set the Id, so combobox could update the selected item. 似乎应该先初始化列表,然后再设置Id,以便组合框可以更新所选项目。 But then why if I use setButton first, then populate, I get expected results(selected item is third item)(only with first use)? 但是那为什么为什么如果我先使用setButton,然后填充,我得到预期的结果(所选项目是第三项)(仅在第一次使用时)?

All you need to do is notify the view that the Id property has changed after you have repopulated the list. 您需要做的就是在重新填充列表之后,通知视图Id属性已更改。

PopulateCommand = new RelayCommand(
    () =>
        {
            Populate();
            RaisePropertyChanged(() => Id);
        });

You won't need to use IsSynchronizedWithCurrentItem=true . 您无需使用IsSynchronizedWithCurrentItem=true This would be used (for instance) to keep two list-boxes synchronized and showing the same selected item. 例如,这将用于使两个列表框保持同步并显示相同的所选项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM