none
combobox下拉框数据源更新后界面不更新的问题 RRS feed

  • 问题

  • 我有个combobox,他的下拉框绑定listPreFunctions,同时listPreFunctions是ListIsAvaililbeFunction的一个实例,里面记录了所有IsAvailibleFunction的状态,当点击了combobox后面的button后,ListIsAvailibleFunction就会把刚刚选择的记录状态改为false。

    按道理来说,接下去选择combobox的候选项的时候,刚刚选择的记录颜色应该变色,但是没有变色,后来我观察过listPreFunctions里对应的记录的状态,的确是更改了,求问为什么没有实现绑定数据的实时改变?

    下面是类的定义,以及xaml,以及其他的一些绑定内容

        public class IsAvailibleFunction
        {
            string function = String.Empty;
            public string Function
            {
                get { return function; }
                set { this.function = value; }
            }
    
            bool isavailible = true;
            public bool Isavailible
            {
                get { return isavailible; }
                set { this.isavailible = value; }
            }
    
            public IsAvailibleFunction()
            { ;}
    
            public IsAvailibleFunction(string function, bool isavailible)
            {
                this.function = function;
                this.isavailible = isavailible;
            }
        }
    
        public class ListIsAvailibleFunctions : ObservableCollection<IsAvailibleFunction>
        { }
          <ComboBox Name="ComboBox_PreFunctions"  MinWidth="150" HorizontalAlignment="Left"
                           SelectedIndex="0" ItemsSource="{StaticResource listPreFunctions}"
                              IsSynchronizedWithCurrentItem="True" 
                              >
                        <ComboBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel/>
                            </ItemsPanelTemplate>
                        </ComboBox.ItemsPanel>
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Function}" Foreground="{Binding Isavailible,Converter={StaticResource functionAvailibleToBrush},Mode=TwoWay}"></TextBlock>
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>


    <my:ListIsAvailibleFunctions x:Key="listPreFunctions"/>
    listPreFunctions = this.Resources["listPreFunctions"] as ListIsAvailibleFunctions;


    2013年7月15日 7:13

答案

  • Hi
    cuso4sean,

    根据您给的代码,我新建了一个WPF的工程。不过未能编译通过,functionAvailibleToBrush这个静态资源您没有在代码中给出。根据您的描述,在comBox后面还有一个Button的,这个Button点击的事件是什么。麻烦您将这部分代码追加上来,这样便于解决这个问题。

    根据您的描述,我大概了解了您的问题。当代码中变量的状态发生改变时,UI并没有进行同步更新。如果是这样的话,发生这样的问题通常有这样一种情况。您定义的IsAvailibleFunction类没有继承INotifyPropertyChanged这个接口。这个接口的作用是提示客户端属性值发生了改变。我给您一段示例代码,您可以参照着修改一些您的IsAvailibleFunction类中需要进行改变的属性值。

    XAML
    Code:

     <StackPanel>
          <TextBox x:Name="myTextBox" Margin="5"/>
          <Button Content="Click me!" x:Name="myButton" Click="myButton_Click" Margin="5"/>
    </StackPanel>

    C#
    Code:

    首先定义一个Person类,这个Person类继承于INotifyPropertyChanged接口,并实现该接口PropertyChanged事件。
      
    class Person : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private string firstName = String.Empty;   
            private Person()
            {
                firstName = "Jimmy";
            }      
            public static Person CreatePerson()
            {
                return new Person();
            }      
            public string FirstName
            {
                get
                {             
                    return firstName;
                }
                set
                {        
                   if (value != firstName)            
                   {    
         this.firstName = value;
         OnPropertyChanged("FirstName");
        }
                }
            }     
    // Create the OnPropertyChanged method to raise the event

            protected void OnPropertyChanged(string name)
            {         
       PropertyChangedEventHandler handler = PropertyChanged;
                if (handler!= null)
                {              
        handler(this, new PropertyChangedEventArgs(name));
                }
            }

    在MainForm中建立Person事例到TextBox的绑定,在Button的Click事件中修改Person实例的FirstName值。

          
     Person person = Person.CreatePerson();
     public MainWindow()
        { 
      InitializeComponent();    
      BindingPersonNameToTextBox();
     }

          
     private void BindingPersonNameToTextBox()
        {
            Binding binding = new Binding("FirstName") { Source = person, Mode = BindingMode.TwoWay };
      this.myTextBox.SetBinding(TextBox.TextProperty, binding);
        }

     private void myButton_Click(object sender, RoutedEventArgs e)
        { 
      person.FirstName += "01";
        }

    编译并运行这个工程,单击Click me按钮,您会发现每点击一次TextBox中的值会增加01。

    为了更好的方便您解决这个问题,您可以参考以下链接。

    #INotifyPropertyChanged Interface
    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

    #ObservableCollection
    http://msdn.microsoft.com/en-us/library/ms668604.aspx

    #ObservableCollection Not Updating UI

    http://stackoverflow.com/questions/1359629/items-in-observablecollection-not-updating-the-view
    http://stackoverflow.com/questions/3521775/observable-collection-not-getting-updated-on-ui-change

    如果您还不能解决这个问题,请联系我。

    Best regards
    Jimmy

    • 已标记为答案 cuso4sean 2013年7月18日 9:07
    2013年7月17日 1:21

全部回复

  • Hi
    cuso4sean,

    根据您给的代码,我新建了一个WPF的工程。不过未能编译通过,functionAvailibleToBrush这个静态资源您没有在代码中给出。根据您的描述,在comBox后面还有一个Button的,这个Button点击的事件是什么。麻烦您将这部分代码追加上来,这样便于解决这个问题。

    根据您的描述,我大概了解了您的问题。当代码中变量的状态发生改变时,UI并没有进行同步更新。如果是这样的话,发生这样的问题通常有这样一种情况。您定义的IsAvailibleFunction类没有继承INotifyPropertyChanged这个接口。这个接口的作用是提示客户端属性值发生了改变。我给您一段示例代码,您可以参照着修改一些您的IsAvailibleFunction类中需要进行改变的属性值。

    XAML
    Code:

     <StackPanel>
          <TextBox x:Name="myTextBox" Margin="5"/>
          <Button Content="Click me!" x:Name="myButton" Click="myButton_Click" Margin="5"/>
    </StackPanel>

    C#
    Code:

    首先定义一个Person类,这个Person类继承于INotifyPropertyChanged接口,并实现该接口PropertyChanged事件。
      
    class Person : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private string firstName = String.Empty;   
            private Person()
            {
                firstName = "Jimmy";
            }      
            public static Person CreatePerson()
            {
                return new Person();
            }      
            public string FirstName
            {
                get
                {             
                    return firstName;
                }
                set
                {        
                   if (value != firstName)            
                   {    
         this.firstName = value;
         OnPropertyChanged("FirstName");
        }
                }
            }     
    // Create the OnPropertyChanged method to raise the event

            protected void OnPropertyChanged(string name)
            {         
       PropertyChangedEventHandler handler = PropertyChanged;
                if (handler!= null)
                {              
        handler(this, new PropertyChangedEventArgs(name));
                }
            }

    在MainForm中建立Person事例到TextBox的绑定,在Button的Click事件中修改Person实例的FirstName值。

          
     Person person = Person.CreatePerson();
     public MainWindow()
        { 
      InitializeComponent();    
      BindingPersonNameToTextBox();
     }

          
     private void BindingPersonNameToTextBox()
        {
            Binding binding = new Binding("FirstName") { Source = person, Mode = BindingMode.TwoWay };
      this.myTextBox.SetBinding(TextBox.TextProperty, binding);
        }

     private void myButton_Click(object sender, RoutedEventArgs e)
        { 
      person.FirstName += "01";
        }

    编译并运行这个工程,单击Click me按钮,您会发现每点击一次TextBox中的值会增加01。

    为了更好的方便您解决这个问题,您可以参考以下链接。

    #INotifyPropertyChanged Interface
    http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

    #ObservableCollection
    http://msdn.microsoft.com/en-us/library/ms668604.aspx

    #ObservableCollection Not Updating UI

    http://stackoverflow.com/questions/1359629/items-in-observablecollection-not-updating-the-view
    http://stackoverflow.com/questions/3521775/observable-collection-not-getting-updated-on-ui-change

    如果您还不能解决这个问题,请联系我。

    Best regards
    Jimmy

    • 已标记为答案 cuso4sean 2013年7月18日 9:07
    2013年7月17日 1:21
  • 的确是没有实现INotifyPropertyChanged接口的原因,多谢

    2013年7月18日 9:07