为什么这个简单的数据绑定方案不起作用? (组合框相关)

问题描述:

我一直在这个片段上挠我的头一阵子,现在很难过。为什么这个简单的数据绑定方案不起作用? (组合框相关)

这个问题场景更容易解释为代码,因此希望它可以说明问题。首先,我有在XAML下面的Silverlight应用程序......

<UserControl x:Class="SilverlightApplication2.Page" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Width="400" Height="300"> 

<UserControl.Resources> 
    <DataTemplate x:Key="icTemplate"> 
     <ComboBox ItemsSource="{Binding StringsChild}" SelectedItem="{Binding SelectedItem}"/> 
    </DataTemplate> 
</UserControl.Resources> 

<Grid x:Name="LayoutRoot" Background="White"> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 
    <ItemsControl x:Name="ic" ItemTemplate="{StaticResource icTemplate}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Vertical"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 

    <Button Click="Save" Grid.Row="1" Content="GO"/> 
</Grid> 

我的代码隐藏看起来像这样...(全部写在一个类文件,使得它的您轻松将它复制到自己的项目并编译)

namespace SilverlightApplication2 
{ 
    public partial class Page : UserControl 
    { 
     public ObservableCollection<SomeClass> StringsParent { get; set; } 

     public Page() 
     { 
      InitializeComponent(); 
      StringsParent = new ObservableCollection<SomeClass>(); 
      ic.ItemsSource = StringsParent; 
     } 

     private void Save(object sender, RoutedEventArgs e) 
     { 
      SomeClass c = new SomeClass(); 
      c.StringsChild.Add("First"); 
      c.StringsChild.Add("Second"); 
      c.StringsChild.SetSelectedItem("Second"); 
      StringsParent.Add(c); 
     } 
    } 

    public class SomeClass 
    { 
     public SelectableObservablecollection<string> StringsChild { get; set; } 

     public SomeClass() 
     { 
      StringsChild = new SelectableObservablecollection<string>(); 
     }  
    } 

    public class SelectableObservablecollection<T> : ObservableCollection<T> 
    { 
     public SelectableObservablecollection() 
      : base() 
     { 

     } 

     public void SetSelectedItem<Q>(Q selectedItem) 
     { 
      foreach (T item in this) 
      { 
       if (item.Equals(selectedItem)) 
       { 
        SelectedItem = item; 
        return; 
       } 
      } 
     } 

     private T _selectedItem; 
     public T SelectedItem 
     { 
      get 
      { 
       return _selectedItem; 
      } 
      set 
      { 
       _selectedItem = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem")); 
      } 
     } 
    } 
} 

所以让我解释... 我开始写创建它有一个的SelectedItem属性,这样一个ObservableCollection的通用方式那当我将集合绑定到ComboBox时,例如,我可以将ComboBox的SelectedItem属性绑定到它。

但是,出于某种原因,ComboBox通过ItemTemplate进行有效嵌套似乎并不奏效。我有效地列出了一个列表,这个脚本非常简单,使我迷失方向。

当您运行代码时,您会看到模板化的ComboBox确实会选取正确的项目,但它从来没有设置为SelectedItem,尽管有绑定。

我知道这是相当长的啰嗦,但是......任何想法?

非常感谢

调试输出实际上给你一个提示的问题:

System.Windows.Data错误:不是在“ExpressionElements.SomeClass”发现“的SelectedItem”属性:BindingExpression路径错误'ExpressionElements.SomeClass'(HashCode = 49044892)。 BindingExpression:Path ='SelectedItem'DataItem ='ExpressionElements.SomeClass'(HashCode = 49044892);目标元素是'System.Windows.Controls.ComboBox'(Name ='');目标属性是'SelectedItem'(类型'System.Object')..

因为模板的Data上下文是SomeClass类的实例,所以您只需将SelectedItem绑定从SelectedItem更改为StringsChild .SelectedItem

<DataTemplate x:Key="icTemplate"> 
    <ComboBox ItemsSource="{Binding StringsChild}" 
    SelectedItem="{Binding StringsChild.SelectedItem}"/> 
</DataTemplate> 
+0

谢谢迈克尔。我不知道为什么我从来没有看过调试器的输出(可能是因为它编译并运行得很好)。再次感谢:) – Senkwe 2009-01-19 19:34:37