更新ItemsSource时出现问题

时间:2012-10-16 19:41:00

标签: wpf data-binding combobox

我有一个可由用户编辑的组合框,因此我将Text属性绑定到我的类的属性。同一个组合框的ItemsSource绑定到AsyncObservableCollection(我根据其他帖子做了,它运行得很好)。

但是,在更新ItemsSource时遇到问题。

以下是重现的步骤:

  1. 在组合框下拉列表中选择一个值。
  2. 在组合框中输入一些文字。 (说“aaa”)
  3. 更新ItemsSource。 (通过我的按钮点击)
  4. 结果:MyText属性保持设置为您键入的文本(“aaa”),但组合框显示空白条目。

    但是,如果您执行上述相同步骤但跳过步骤1,则组合框会正确显示MyText属性中的文本。这使我相信在完成对ItemsSource的更新后,所选索引/选定值将用于更新组合框。

    有关如何在更新ItemsSource后保持显示的值与MyText属性同步的任何想法?

    在下面提供的代码中,我在按钮点击时更新ItemsSource以便重现。

    谢谢!

    XAML:

    <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="200" IsEditable="True"
                              DataContext="{Binding Path=MyDataClass}"
                              ItemsSource="{Binding Path=MyListOptions}"
                              SelectedIndex="{Binding Path=MySelectedIndex}"
                              Text="{Binding Path=MyText, UpdateSourceTrigger=LostFocus}"
                  >
        </ComboBox>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="416,276,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
    

    代码背后:

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows;
    using System.Diagnostics;
    
    namespace WpfApplication2
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public class DataClass : INotifyPropertyChanged
            {
                private string mytext = "";
                public string MyText
                {
                    get
                    {
                        return mytext;
                    }
                    set
                    {
                        mytext = value;
                        OnPropertyChanged("MyText");
                    }
                }
    
                private int myselectedindex = -1;
                public int MySelectedIndex 
                {
                    get
                    {
                        return myselectedindex;
                    }
    
                    set
                    {
                        if (value != -1)
                        {
                            mytext = MyListOptions[value];
                            OnPropertyChanged("MyText");
                        }
                    }
                }
    
                private AsyncObservableCollection<string> mylistOptions = new AsyncObservableCollection<string>();
                public AsyncObservableCollection<string> MyListOptions
                {
                    get
                    {
                        return mylistOptions;
                    }
    
                    set
                    {
                        mylistOptions.Clear();
                        OnPropertyChanged("MyListOptions");
                        foreach (string opt in value)
                        {
                            mylistOptions.Add(opt);
                        }
                        OnPropertyChanged("MyListOptions");
                    }
                }
    
                public DataClass()
                {
                }
    
                public event PropertyChangedEventHandler PropertyChanged;
    
                internal void OnPropertyChanged(string prop)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(prop));
                }
            }
    
            public DataClass MyDataClass { get; set; }
    
            public MainWindow()
            {
                MyDataClass = new DataClass();
    
                MyDataClass.MyListOptions.Add("Option 1 - Provides helpful stuff.");
                MyDataClass.MyListOptions.Add("Option 2 - Provides more helpful stuff.");
                MyDataClass.MyListOptions.Add("Option 3 - Provides extra helpful stuff.");
    
                InitializeComponent();
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                AsyncObservableCollection<string> newList = new AsyncObservableCollection<string>();
                newList.Add("Option A - Provides helpful stuff.");
                newList.Add("Option B - Provides more helpful stuff.");
                newList.Add("Option C - Provides extra helpful stuff.");
    
                MyDataClass.MyListOptions = newList;
    
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

好的,我通过将SelectedValue绑定到与Text相同的属性并将其模式设置为OneWay来解决此问题。

    <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="200" IsEditable="True"
                          DataContext="{Binding Path=MyDataClass}"
                          ItemsSource="{Binding Path=MyListOptions}"
                          SelectedIndex="{Binding Path=MySelectedIndex}"
                          SelectedValue="{Binding Path=MyText, Mode=OneWay}"
                          Text="{Binding Path=MyText, UpdateSourceTrigger=LostFocus}"