0

私はComboBoxXAMLで使用しています:

 <ComboBox x:Name="Combobox1" ItemsSource="{Binding}" Margin="0,0,300,0"  
           Width="100" FontSize="30"   />

コード ビハインドでは、その値を次のように設定しています。

 protected override void OnNavigatedTo(NavigationEventArgs e)
 {
     Combobox1.DataContext = ComponentDataSource.ComponentCollection;
 }

今、私はデータソースを持っています:

public class ComponentDataSource
{      
    private static ObservableCollection<ComponentGroup> _componentcollection;    

    public static ObservableCollection<ComponentGroup> ComponentCollection
    {
        get { return _componentcollection; }
    }


    public static async void CheckJson(object sender, object e)
    {
        var client = new HttpClient();
        client.MaxResponseContentBufferSize = 1024 * 1024;

        try
        {
            var response = await client.GetAsync(new Uri("URI"));
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            var jobj = JObject.Parse(result);

            var list = jobj.Children()
                .Cast<JProperty>()
                .Select(p => new ComponentGroup()
                {
                    Name = p.Name,
                    Type = (string)p.Value["P1"],
                    Value = (string)p.Value["P2"]
                })
                .ToList();

            _componentcollection = new ObservableCollection<ComponentGroup>(list);
        }
        catch (HttpRequestException ex)
        {
        }
    }
}

何らかの理由で、これらのアイテムが に表示されませんComboBox。私が得るのは空のComboBox.

誰でも私を助けてもらえますか?

編集 1: こんにちは、私は単純なものが欠けていることを知っていますが、誰かが私を助けてくれれば、私はそれを高く評価します. ところで、コードが必要な場合はお知らせください。skydrive にアップロードします。

4

2 に答える 2

2

コードには、空の結果になる可能性のあるものがいくつかありますComboBox

  • Web サービスは実際に結果を返していますか? あなたが飲み込んでいるその例外は、あなたが実際に空の(またはnull)リストで作業しているという事実を隠すかもしれません. これはあなたの問題ではありませんが、問題になる可能性があります。

  • コレクションに要素があり、コードビハインドを使用していると仮定すると、単純にItemsSourceプロパティを割り当ててみませんか?

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        Combobox1.ItemsSource = ComponentDataSource.ComponentCollection;
    }
    

    コレクションが空でない場合は、アイテムが表示されます。

他の人が示唆していることにもかかわらず、静的プロパティにバインドしていないため、バインディングは正しいです。オブジェクトにバインドしていて、DataContextこれを静的プロパティの値に設定します。コンボ ボックスの に割り当てる前にコレクションnullに値がなく、値がある場合は、項目が表示されます。DataContext

あなたの場合に起こっていると私が想定しているのは、DataContextを の値に設定するかnull、最良の場合は空のコレクションに設定していることです。

あなたのCheckJsonメソッドは のイベント ハンドラーに非常によく似ているDispatchTimerので、Web から要素を定期的にダウンロードしてコンボ ボックスに表示していると想定しています。ただし、そうするたびに、それらを含むコレクションを新しいObservableCollection!

私の 2 つの仮定をテストするCheckJsonには、DataContext.

特にコレクションが静的であるため、問題を解決する最も簡単な方法は、 (たとえば、クラスの静的コンストラクターに、または宣言時に初期化することによって) をObservableCollection1 回格納し、必要に応じて、、またはアイテムを単純に格納することです。コンボ ボックスは常に同じリストをリッスンするため、内容が変更されると通知されます。あなたが持っているでしょう:_componentcollectionAddRemoveClear

private static ObservableCollection<ComponentGroup> _componentcollection = new ObservableCollection<ComponentGroup>();

ではCheckJson、次のように置き換えます。

_componentcollection = new ObservableCollection<ComponentGroup>(list);

と:

_componentcollection.Clear();

foreach (var item in list)
{
    _componentcollection.Add(item);
}

PS。上記の直接使用するという私の提案はItemsSource、現在のコードとまったく同じ問題に悩まされます。それは、バインディングを写真から取り除き、バインディングが問題ではないことを証明するだけです。ObservableCollectionたとえば、回答の最後に提案するように、単一のものを使用して、静的コードのリストを置き換えないように注意する必要があります。

于 2013-05-08T15:53:33.020 に答える
2

Vasile はコメントでそれを正しく示しています。Windows 8 アプリの XAML は静的プロパティにバインドできません。XAML は、次のような標準プロパティにバインドできます。

public string Name { get; set; }

それ(上記)はequivと結合します。の{Binding Mode=OneTime}。これは、更新がイベントを発生させるためです。同時に、次のように完全にイベント化されたプロパティを使用できます。

string m_Name = default(string);
public string Name { get { return m_Name; } set { SetProperty(ref m_Name, value); } }

これは XAML でバインドされ、指定したモード ( OneTimeOneWayTwoWay) をサポートします。それはINotifyPropertyChangedパターンに従い、かなり基本的です。

私はこれを言うためにすべてを言います。これら 2 つのアプローチは、バインドする唯一の方法です。フィールドにバインドすることはできません。メソッドにバインドすることはできません (まだ)。また、静的プロパティにバインドすることはできません。静的プロパティにバインドする必要がある場合は、静的プロパティをビュー モデルの標準プロパティに公開するだけです。

私が真実を語っていることを示すために、次の XAML を考えてみましょう (あなたのものとほとんど同じです)。

<ComboBox x:Name="MyCombo" ItemsSource="{Binding}" />

これを試すと、問題なくバインドされます。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    this.MyCombo.DataContext = new MyModel().Items;
    base.OnNavigatedTo(e);
}

public class MyModel
{
    public MyModel()
    {
        foreach (var item in Enumerable.Range(1, 50))
            Items.Add(item);
    }
    ObservableCollection<int> m_Items = new ObservableCollection<int>();
    public ObservableCollection<int> Items { get { return m_Items; } }
}

両者の唯一の違いはstatic部品です。したがって、試している方法で値をプッシュしても機能しません。これは、静的プロパティに直接バインドしているためです。

バインドして公開する方法は次のとおりstatic です

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    this.MyCombo.DataContext = new MyModel().Items;
    base.OnNavigatedTo(e);
}

public class MyModel
{
    public MyModel()
    {
        foreach (var item in Enumerable.Range(1, 50))
            s_Items.Add(item);
    }
    private static ObservableCollection<int> s_Items = new ObservableCollection<int>();
    public ObservableCollection<int> Items { get { return s_Items; } }
}

上記のコードでは、クラスに値 static がありますがMyModel、それを公開する標準プロパティがあります。ObservableColelctionプロパティはバインドのために既にイベント化されているため、これが完全な実装になる可能性があります。だからあなたは手に入れstatic 拘束します。わかる?

さて、恥ずかしい部分に。

質問をバインドするために使用している手法が機能するはずです。静的プロパティをにバインドしてから、DataContextそれにバインドすると機能しItemsSourceます。@maad0 は、それが優れたアプローチであることを実証しました。では、なぜうまくいかないのでしょうか。

私が言えることは、「あなたが間違っているからではありません」ということだけです。<blush />私は自分の回答を削除したくなりましたが、そうしようとしている開発者にとって静的バインディングの説明が価値があるかもしれないという理由だけで残しています。

これでコードをテストします

これが CheckJson メソッドです。実際に結果が得られているかどうかを確認するために、デバッガー ステートメントを追加しました。アプリでこのサンプルを使用して、問題が発生するかどうかを確認してください。壊れない場合、問題はデータがないことではありません。問題はどういうわけかあなたのバインディングにあります。それは私にはすべてうまく見えますが。

public static async void CheckJson(object sender, object e)
{
    var client = new HttpClient();
    client.MaxResponseContentBufferSize = 1024 * 1024;

    try
    {
        var response = await client.GetAsync(new Uri("URI"));
        response.EnsureSuccessStatusCode();
        var result = await response.Content.ReadAsStringAsync();
        var jobj = JObject.Parse(result);

        var list = jobj.Children()
            .Cast<JProperty>()
            .Select(p => new ComponentGroup()
            {
                Name = p.Name,
                Type = (string)p.Value["P1"],
                Value = (string)p.Value["P2"]
            })
            .ToList();

        // add this code
        if (!_componentcollection.Any())
            System.Diagnostics.Debugger.Break();

        _componentcollection = new ObservableCollection<ComponentGroup>(list);
    }
    catch (HttpRequestException ex)
    {
    }
}
于 2013-05-08T15:35:56.540 に答える