在Silverlight中绑定ComboBox.SelectedItem

在Silverlight中绑定ComboBox.SelectedItem,silverlight,data-binding,combobox,selecteditem,Silverlight,Data Binding,Combobox,Selecteditem,这件事快把我逼疯了。以下是XAML: <UserControl x:Class="SilverlightApplication1.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid x:Name="LayoutRoot" Backgro

这件事快把我逼疯了。以下是XAML:

    <UserControl x:Class="SilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid x:Name="LayoutRoot" Background="White">
    <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
      <ComboBox ItemsSource="{Binding Path=Thing.Stuff}"
                SelectedItem="{Binding Path=Thing.SelectedStuff}">
        <ComboBox.ItemTemplate>
          <DataTemplate>
            <TextBlock Text="{Binding Path=Name}" />
          </DataTemplate>
        </ComboBox.ItemTemplate>
      </ComboBox>
      <Button Content="Again" Click="Button_Click" />
    </StackPanel>
  </Grid>
</UserControl>

代码背后:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace SilverlightApplication1
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            Data data = new Data();
            data.Thing = new Thing();
            data.Thing.Stuff = new ObservableCollection<Stuff>();
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 1" } );
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 2" } );
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 3" } );
            data.Thing.SelectedStuff = data.Thing.Stuff.Last();
            DataContext = data;
        }

        private void Button_Click( object sender, RoutedEventArgs e )
        {
            Data data = ( DataContext as Data );
            data.Thing.Stuff.Clear();
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 4" } );
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 5" } );
            data.Thing.Stuff.Add( new Stuff { Name = "Stuff 6" } );
            data.Thing.SelectedStuff = data.Thing.Stuff.Last();
        }
    }

    public class Data : INotifyPropertyChanged
    {
        private Thing _Thing;

        public Thing Thing
        {
            get { return _Thing; }
            set { _Thing = value; NotifyPropertyChanged( "Thing" ); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged( string propertyName )
        {
            if ( PropertyChanged == null ) { return; }
            PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
        }
    }

    public class Thing : INotifyPropertyChanged
    {
        private ObservableCollection<Stuff> _Stuff;

        public ObservableCollection<Stuff> Stuff
        {
            get { return _Stuff; }
            set { _Stuff = value; NotifyPropertyChanged( "Stuff" ); }
        }

        private Stuff _SelectedStuff;

        public Stuff SelectedStuff
        {
            get { return _SelectedStuff; }
            set { _SelectedStuff = value; NotifyPropertyChanged( "SelectedStuff" ); }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged( string propertyName )
        {
            if ( PropertyChanged == null ) { return; }
            PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
        }
    }

    public class Stuff : INotifyPropertyChanged
    {

        private string _Name;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; NotifyPropertyChanged( "Name" ); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged( string propertyName )
        {
            if ( PropertyChanged == null ) { return; }
            PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
        }
    }
}
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
命名空间SilverlightApplication1
{
公共部分类页面:UserControl
{
公共网页()
{
初始化组件();
数据=新数据();
data.Thing=新事物();
data.Thing.Stuff=新的ObservableCollection();
data.Thing.Stuff.Add(newstuff{Name=“Stuff 1”});
data.Thing.Stuff.Add(newstuff{Name=“Stuff 2”});
data.Thing.Stuff.Add(newstuff{Name=“Stuff 3”});
data.Thing.SelectedStuff=data.Thing.Stuff.Last();
数据上下文=数据;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
数据=(数据上下文作为数据);
data.Thing.Stuff.Clear();
data.Thing.Stuff.Add(newstuff{Name=“Stuff 4”});
data.Thing.Stuff.Add(newstuff{Name=“Stuff 5”});
data.Thing.Stuff.Add(newstuff{Name=“Stuff 6”});
data.Thing.SelectedStuff=data.Thing.Stuff.Last();
}
}
公共类数据:INotifyPropertyChanged
{
私事;
公共事物
{
获取{return\u Thing;}
设置{u Thing=value;NotifyPropertyChanged(“Thing”);}
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
如果(PropertyChanged==null){return;}
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类事物:INotifyPropertyChanged
{
私人可观察收集的资料;
公众可观察的收集材料
{
获取{return\u Stuff;}
设置{u Stuff=value;NotifyPropertyChanged(“Stuff”);}
}
私人物品(你选择的物品);;
公共物品精选物品
{
获取{return\u SelectedStuff;}
设置{u SelectedStuff=value;NotifyPropertyChanged(“SelectedStuff”);}
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
如果(PropertyChanged==null){return;}
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类Stuff:INotifyPropertyChanged
{
私有字符串\u名称;
公共字符串名
{
获取{return\u Name;}
设置{u Name=value;NotifyPropertyChanged(“Name”);}
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
如果(PropertyChanged==null){return;}
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
加载页面时,会出现一个选择了“Stuff 3”的组合框。单击按钮时,组合框中的项目将更改,但应选择“Stuff 6”。相反,未选择任何内容。

请尝试以下操作:

 <ComboBox ItemsSource="{Binding Path=Thing.Stuff}"                
      SelectedItem="{Binding Path=Thing.SelectedStuff, Mode=TwoWay}">


SelectedItem不喜欢单向绑定。我还没有机会在Silverlight 2中试用,但在Silverlight 3中,如果不使用双向绑定,您甚至会得到黄色的死亡三角。

当然,绑定必须是双向的。但将ItemsSource设置为控件并不意味着设置了DataContext(SelectedItem变量应指向的位置)。确保combo的DataContext设置正确。(在我的例子中,to Page.As selectedStuff是一个页面属性

cmbStuff.DataContext = Me '(from  Page.Load)

如果有什么安慰的话,它在WPF中对我很有效(我将了解Silverlight)。刚刚验证了这在SL2中修复了它。很好的发现在这个示例中确实修复了它,但在我的大项目中没有。不确定那里发生了什么。嗯,如果你能提供更多关于你的大项目与这里提供的示例有什么不同的细节,那么我们可能能够更好地诊断问题。我发布了一个新问题关于此,请提供更多信息: