【问题标题】:Why does this simple databinding scenario not work? (ComboBox related)为什么这个简单的数据绑定场景不起作用? (组合框相关)
【发布时间】:2010-10-02 07:10:51
【问题描述】:

我已经在这个问题上摸不着头脑了一段时间,现在被难住了。

问题场景更容易解释为代码,因此希望它不言自明。首先,我在 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,尽管进行了绑定。

我知道这很啰嗦,但是……有什么想法吗?

非常感谢

【问题讨论】:

    标签: silverlight data-binding combobox selecteditem itemssource


    【解决方案1】:

    调试器输出实际上为您提供了问题的提示:

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

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

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

    【讨论】:

    • 谢谢迈克尔。我不知道为什么我从不费心查看调试器的输出(可能是因为它在大多数情况下编译和运行都很好) 经验教训。再次感谢:)
    • 不客气。我对模板很感兴趣;它非常强大:blogs.msdn.com/synergist/archive/2009/01/19/…
    猜你喜欢
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2016-09-26
    • 2010-10-26
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多