C# 只是好奇:为什么WPF绑定到控件';什么东西坏了?

C# 只是好奇:为什么WPF绑定到控件';什么东西坏了?,c#,wpf,data-binding,controls,C#,Wpf,Data Binding,Controls,我熟悉WPF绑定和MVVM。有一天,我在回答问题时遇到了这样的情况: <Grid> <ListBox Name="lb" DisplayMemberPath="S"/> </Grid> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.lb.ItemsSource =

我熟悉WPF绑定和MVVM。有一天,我在回答问题时遇到了这样的情况:

<Grid>
    <ListBox Name="lb" DisplayMemberPath="S"/>
</Grid>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.lb.ItemsSource = new ObservableCollection<Item>()
        {
            new Item("aa"),
            new Item("bb"),
            new Item("cc"),
        };
    }
}

public class Item : ListBoxItem //
{
    public Item(string s)
    {
        this.S = s;
    }
    public string S { get; set; }
}

公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
this.lb.ItemsSource=新的ObservableCollection()
{
新项目(“aa”),
新项目(“bb”),
新项目(“cc”),
};
}
}
公共类项:ListBoxItem//
{
公共项目(字符串s)
{
这个.S=S;
}
公共字符串S{get;set;}
}
如果项继承ListBoxItem或其他控件,则不显示任何内容。
但是为什么呢?S不总是对象的属性吗?

当您将
ItemsSource
绑定到数据时,它会为每个元素创建一个
ListBoxItem
,并使用指定的
DisplayMemberPath
显示它。但是,如果您绑定到您自己在代码隐藏中创建的
ListBoxItem
数组,那么它将使用这些数组。在您发布的代码中,您的
Item
类继承了
ListBoxItem
,因此它是GUI元素,而不是数据。这是一种糟糕的做法,但如果这是您真正想要做的,那么您不需要
s
属性,只需直接设置
内容

public class Item : ListBoxItem
{
    public Item(string s)
    {
        this.Content = s;
    }
}
但是,如果您希望正确地执行此操作(例如MVVM),则不要继承
ListBoxItem
,也不要直接在代码隐藏中操作UI元素:

public class Item
{
    public Item(string s)
    {
        this.S = s;
    }
    public string S { get; set; }
}

ItemsSource
绑定到数据时,它会为每个元素创建一个
ListBoxItem
,并使用指定的
DisplayMemberPath
显示它。但是,如果您绑定到您自己在代码隐藏中创建的
ListBoxItem
数组,那么它将使用这些数组。在您发布的代码中,您的
Item
类继承了
ListBoxItem
,因此它是GUI元素,而不是数据。这是一种糟糕的做法,但如果这是您真正想要做的,那么您不需要
s
属性,只需直接设置
内容

public class Item : ListBoxItem
{
    public Item(string s)
    {
        this.Content = s;
    }
}
但是,如果您希望正确地执行此操作(例如MVVM),则不要继承
ListBoxItem
,也不要直接在代码隐藏中操作UI元素:

public class Item
{
    public Item(string s)
    {
        this.S = s;
    }
    public string S { get; set; }
}