1

我的代码上有两个ComboBox

<ComboBox Name="comboBoxSelectCamera" ItemsSource="{Binding Path=ListCameras}" SelectionChanged="comboBoxSelectCamera_SelectionChanged" />
<ComboBox Name="comboBoxCities" ItemsSource="{Binding Path=ListCities}" />    

在我的身上,Window我有这段代码,所以ComboBox了解它的Path来源:

<Window ....
     DataContext="{Binding RelativeSource={RelativeSource Self}}"
     .... >

两个组合都绑定到我在我创建的两个列表MainWindow

public MainWindow()
{
    InitializeCitiesCombo();

    InitializeComponent();

    // Initialize the control that checks for cameras
    InitializeCameraControl();
    FillCameraProperties();
    DataContext = this;
}

第一个ComboBox列表是在之前创建的InitializeComponent,所以当它的组合创建时,它会填充特定的内容。

第二个ComboBox列表是在之后创建的InitializeComponent,因为它依赖于加载相机的对象,而且,我不知道是不是这个原因,但是如果列表是在之后 InitializeComponent创建的,它不会填充ComboBox.

我知道还有其他方法可以在我的计算机上填写已连接摄像机的列表,但我必须使用InitializeComponentInitializeCameraControl().

关于我如何ComboBox在之后填写这个的任何想法InitializeComponent

编辑:两个列表的声明:

private List<CameraInfo> ListCameras { get; set; } 
private List<String> ListCities { get; set; }

在代码的某处,ListCites

ListCities = new List<String> { Madrid, Barcelona, Alicante, Valencia }

在代码中的某处,我的控件返回已连接摄像机的列表(它有效,它有元素,但它们不显示在组合中):

ListCameras = MyUserControl.ConnectedCameras;  // this returns a valid list of `CameraInfo`

我的CameraInfo班级:

public class CameraInfo
{
    public CameraInfo(string name, string id);

    public static implicit operator string(CameraInfo cameraInfo);

    public string Id { get; }
    public string Name { get; }

    public override string ToString();
}

请注意,在我们讨论这个问题时,我尝试将相机组合更改为DisplayMemberPath.

绑定错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'Text' property not found on 'object' ''MainWindow' (Name='')'. BindingExpression:Path=Text; DataItem='MainWindow' (Name=''); target element is 'TextBox' (Name=''); target property is 'Template' (type 'ControlTemplate')
4

1 回答 1

2

好的,这是你的主要问题。首先,像这样更改您的列表。

private ObservableCollection<CameraInfo> _listCamera; 
public ObservableCollection<CameraInfo> ListCameras
{
    get { return _listCamera ?? (_listCamera = new ObservableCollection<CameraInfo>()); }
}

我只为一个列表显示它,但你必须为两者都这样做。要填写列表,请不要重新实例化它们,而是清除它们。例如

private void FillCameraInfo()
{
    IEnumerable<CameraInfo> example = new[] { new CameraInfo(), new CameraInfo() };
    ListCameras.Clear();
    foreach(var exampleEntry in example)
        ListCameras.Add(exampleEntry);
}

这只是一个例子,所以我尽可能简单。如果您要重新实例化它们,则绑定将被“销毁”。

第一个ComboBox正确填充的事实在于您在使用它们的绑定初始化组件之前填充它。所以可以找到物品。第二个ComboBox不知道 中的更改ListCities,因为它没有通知它。如果您使用ObservableCollection<T>ComboBox收到通知,请在此处查看更多信息。并且绑定应该按预期工作。

编辑 - 为什么你不应该重新实例化集合

如果您要执行以下操作以将数据放入集合中

public FillCameraInfo()
{
    ListCameras = new ObservableCollection<CameraInfo>(someData); 
}

绑定仍然会监听“旧”实例。但是你改变了引用,ListCameras没有人听新的实例。

编辑 - 为什么你什么都看不到

好吧,这有点奇怪,但它就是这样。绑定的声明顺序ComboBox非常重要,这样它才能正常工作。请在此处查看正确的顺序。

于 2013-04-25T08:37:08.783 回答