2011-02-08 17 views
2

データバインドでリフレッシュの問題が発生しましたComboBox コードビハインドからSelectedValueを変更すると、選択が更新されません。 問題を説明するサンプルを以下に示します。私は何か間違っているのですか?SilverlightデータバインドSelectedValueを設定したときにComboBoxが更新されない

ありがとうございます!


<navigation:Page x:Class="Views.TestCB" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      mc:Ignorable="d" 
      xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" 
      d:DesignWidth="640" d:DesignHeight="480" 
      DataContext="{Binding RelativeSource={RelativeSource Self}}" 
      Title="TestCB Page"> 
    <Grid x:Name="LayoutRoot"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
     </Grid.ColumnDefinitions> 
     <ComboBox ItemsSource="{Binding AllItems, Mode=TwoWay}" Grid.Row="0" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" DisplayMemberPath="Key" SelectedValuePath="Value" SelectedValue="{Binding SelectedValue, Mode=TwoWay}"/> 
     <Button Content="Change" Click="Button_Click" Grid.Row="1" /> 
     <Button Content="Display" Click="Button_Click_1" Grid.Row="2" /> 
    </Grid> 
</navigation:Page> 

public partial class TestCB : Page, INotifyPropertyChanged 
{ 
    public TestCB() 
    { 
     InitializeComponent(); 
    } 

    private Random r = new Random(); 

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

    private ObservableCollection<MyClass> allItemsField = new ObservableCollection<MyClass>(); 
    public ObservableCollection<MyClass> AllItems 
    { 
     get 
     { 
      return this.allItemsField; 
     } 

     set 
     { 
      if (this.allItemsField != value) 
      { 
       this.allItemsField = value; 
       this.OnPropertyChanged("AllItems"); 
      } 
     } 
    } 

    private MyClass selectedItemField = null; 
    public MyClass SelectedItem 
    { 
     get 
     { 
      return this.selectedItemField; 
     } 

     set 
     { 
      if (this.selectedItemField != value) 
      { 
       this.selectedItemField = value; 
       this.OnPropertyChanged("SelectedItem"); 
      } 
     } 
    } 

    private int selectedValueField; 
    public int SelectedValue 
    { 
     get 
     { 
      return this.selectedValueField; 
     } 

     set 
     { 
      if (this.selectedValueField != value) 
      { 
       this.selectedValueField = value; 
       this.OnPropertyChanged("SelectedValue"); 
      } 
     } 
    } 

    protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
     this.SetCombo(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     this.SetCombo(); 
     this.SelectRandom(); 
    } 

    private void SetCombo() 
    { 
     this.AllItems.Clear(); 

     int generated = 0; 
     while (generated < 10) 
     { 
      int val = r.Next(100); 
      string key = string.Format("Key #{0}", val); 

      if (!this.AllItems.Any(e => e.Key == key)) 
      { 
       this.AllItems.Add(new MyClass { Key = key, Value = val }); 
       generated++; 
      } 
     } 
    } 

    private void SelectRandom() 
    { 
     var tmp = this.AllItems[r.Next(this.AllItems.Count)]; 
     this.SelectedValue = tmp.Value; 
    } 

    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     MessageBox.Show(this.SelectedItem.Key); 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    private int valueField; 
    public int Value 
    { 
     get 
     { 
      return this.valueField; 
     } 

     set 
     { 
      if (this.valueField != value) 
      { 
       this.valueField = value; 
       this.OnPropertyChanged("Value"); 
      } 
     } 
    } 

    private string keyField = string.Empty; 
    public string Key 
    { 
     get 
     { 
      return this.keyField; 
     } 

     set 
     { 
      if (this.keyField != value) 
      { 
       this.keyField = value; 
       this.OnPropertyChanged("Key"); 
      } 
     } 
    } 
} 

EDIT:私のプログラムでは、ComboBoxListBoxItemの一部(ListBoxもデータバインドさである)であるので、私はそれを直接アクセスすることはできませんのでご注意くださいバインディングをリセットする/リロードを強制する。

答えて

0

代わりにSelectedItemを設定しましたか? SelectedValueには、いくつかのものがあります。know issues

+0

私の場合は解決策ではないようです。私は実際のアプリケーション、ListBoxがあり、各ListBoxItemにはコンボボックスがあります。これらのコンボボックスは、コードの背後にあるコレクションにバインドされ、選択された値は、リストボックスからバインドされたオブジェクトのプロパティです。問題は、バインドされたオブジェクトがコレクション内のオブジェクトのメンバーであるID(int)のみを認識し、オブジェクト全体は認識しないことです。私はコンバーターを試しましたが、コレクション全体にアクセスできないので、コンボボックスに直接アクセスできないので、ItemsSourceを読むことさえできません... – Shimrod

関連する問題