C# 对象列表到列表框的非常简单的绑定

C# 对象列表到列表框的非常简单的绑定,c#,wpf,wpf-controls,C#,Wpf,Wpf Controls,鉴于以下情况,如何在DeviceListBox中仅显示DeviceName属性 namespace NotMyNS { public class Device { public int SerialNumber { get; set; } public string DeviceName { get; set; } } } namepace MyNS { public partial class myControl : U

鉴于以下情况,如何在DeviceListBox中仅显示DeviceName属性

namespace NotMyNS
{
    public class Device
    {
        public int SerialNumber { get; set; }
        public string DeviceName { get; set; }
    }
}

namepace MyNS
{    
    public partial class myControl : UserControl
    {
        public ObservableCollection<NotMyNS.Device> DeviceList { get; set; }
    }
}

<UserControl x:Class="MyNS.myControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">    
    <Grid >        
        <ListBox Name="DeviceListBox" />
    </Grid>
</UserControl>
namespace NotMyNS
{
公共类设备
{
公共整数序列号{get;set;}
公共字符串DeviceName{get;set;}
}
}
名称空间MyNS
{    
公共部分类myControl:UserControl
{
公共可观察收集设备列表{get;set;}
}
}
我已经看过许多示例,但无法将我看到的内容应用于我的问题。

您可以设置要从视图模型中显示的属性。另外,如果您想将
DeviceList
用作
ItemsSource
,则需要将绑定上下文指定为
UserControl

<ListBox 
   ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DeviceList}" 
   DisplayMemberPath="DeviceName" />

您应该使用
DisplayMemberPath

<ListBox Name="DeviceListBox" ItemsSource="{Binding DeviceList}" DisplayMemberPath="DeviceName"  />


在这种情况下。您需要在
ListBox.ItemsSource
中创建
DataTemplate
。创建一个
文本块
并将其绑定到DeviceName。

您还必须设置DataContext。将“DataContext=this;”添加到myControl构造函数中。 或者您可以这样做,而无需设置DataContext

<ListBox Name="DeviceListBox" ItemsSource="{Binding RelativeSource={RelativeSource
        FindAncestor,AncestorType={x:Type Window}},Path=DeviceList}" DisplayMemberPath="DeviceName"/>


对于这样简单的情况来说,它太多余了。请参阅@tencntraze给出的答案。他提到了关于这个问题的任何建议好的,那就是。。。我显然是认真地考虑过了项目资源绑定。我试图使用静态资源和其他各种想法。恶魔主义者一开始是空的,事件会给它添加一些东西。即使我使用的是ObservableList,这些添加的项目也不会出现在屏幕上。我必须做些什么来刷新列表框吗?除非您要替换
DeviceList
属性,否则不必做任何事情,在这种情况下,您需要通过
INotifyPropertyChanged
接口发出属性已更改的信号。如何添加项?像这样(因为添加设备的事件位于不同的线程上):DeviceListBox.Dispatcher.Invoke(新操作(()=>DeviceList.Add(设备)),null);你的代码几乎适合我。如果我省略DisplayMemberPath,我会在列表框中得到项目,但它们的形式是“NotMyNS.Device”。我假设DeviceName被定义为公共字符串DeviceName{get;set;}它可能不是,它可能只是公共字符串DeviceName;这会导致DisplayMemberPath出现问题吗?是的,这很重要。它必须是公共财产,不能与字段一起使用。您能确认它是字段还是属性吗?不,NoyMyNS是来自第三方dll的命名空间。因此,我将设备克隆到使用属性的myDevice中,并在列表框中获得了播发的DeviceName(因此我可以假设dll使用的字段)。