1

ComboBox私のコードには2つあります:

<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}}"
     .... >

両方のコンボは、自分で作成した 2 つのリストにバインドされていMainWindowます。

public MainWindow()
{
    InitializeCitiesCombo();

    InitializeComponent();

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

最初のComboBoxリストはのに作成されるInitializeComponentため、そのコンボが作成されると、特定のコンテンツで埋められます。

2 番目の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>()); }
}

1 つのリストに対してのみ表示していますが、両方に対して行う必要があります。リストを埋めるには、それらを再インスタンス化せずにクリアします。例えば

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

あくまでも一例ですので、なるべくシンプルにまとめました。それらを再インスタンス化すると、バインディングは「破棄」されます。

最初のComboBoxものが正しく埋められているということは、コンポーネントをバインディングで初期化する前に、それを埋めているという事実にあります。そのため、アイテムを見つけることができます。2 つ目は、通知を受けていないためComboBox、 の変更を認識していません。ListCitiesをご利用ObservableCollection<T>の場合ComboBoxはお知らせいたしますので、詳しくはこちらをご覧ください。そして、バインディングは期待どおりに機能するはずです。

編集 - コレクションを再インスタンス化してはいけない理由

次のようにしてデータをコレクションに入れる場合

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

バインディングは引き続き「古い」インスタンスをリッスンします。しかし、参照を変更したためListCameras、誰も新しいインスタンスをリッスンしません。

編集 - 何も表示されない理由

わかりました、これは少し奇妙ですが、そうです。バインディングの宣言の順序は、ComboBox適切に機能するために非常に重要です。正しい順番はこちらをご覧ください。

于 2013-04-25T08:37:08.783 に答える