2013-05-08 83 views
0

我使用ComboBox在XAML:組合框無法設置的DataContext

<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。

+1

嗯......虛擬機中的一切都是靜態的。在XAML中執行綁定時,必須設置ItemsSource = {Binding ComponentCollection}(ObservableCollection),並在DataContext上需要類Component Data Source的實例。但既然它有靜態的方法,我不知道它會怎麼做的伎倆... – VasileF 2013-05-08 09:05:50

+0

@Vasile MarianFălămaş,我應該做任何方法實例方法,而不是靜態? – 2013-05-08 09:54:48

+0

標記最佳/正確答案是禮貌的。 – 2013-06-20 15:31:10

回答

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模式,並且非常基礎。

我說這一切。這兩種方法是綁定的唯一方式。你不能綁定到一個字段。你不能綁定到一個方法(還)。你不能綁定到一個靜態屬性。 如果您必須綁定到靜態屬性,請將您的靜態屬性暴露在視圖模型中的標準屬性中。

要告訴你,我說的是實話,考慮這個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; } } 
} 

在上面的代碼,我在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) 
    { 
    } 
} 
+1

除了他沒有綁定到靜態屬性,他綁定到他的'DataContext'。存儲在'DataContext'中的值來自靜態屬性的事實也不是問題。問題是他每次調用「CheckJson」時都會替換這個值,但綁定引擎並不知道它。 – madd0 2013-05-08 15:56:35

+1

綁定到靜態屬性或綁定到引用與靜態屬性相同的值的DataContext並不是同一件事。他正在做後者,它的工作原理。如果你喜歡,我可以向你發送一個示例應用程序來證明它。 – madd0 2013-05-08 16:40:16

+0

你說得對。 100%。感謝您花時間向我展示。我的測試項目對於綁定'DataContext'是不準確的。清楚的是,您可以將一個靜態屬性綁定到'DataContext',然後將'ItemsSource'綁定到'DataContext'。這是有效的 - 儘管它需要代碼來完成它。您不能僅從XAML靜態屬性綁定。我更新了我的答案以反映這一點。 – 2013-05-08 22:04:05

2

有代碼中的幾件事情,可能會導致空ComboBox

  • 是Web Service實際上返回的結果嗎?您吞嚥的異常可能會隱藏您實際使用空白(或null)列表的事實。這不是你現在的問題,但可能是。

  • 假設您的收藏包含元素,並且由於您使用的是代碼,爲什麼不簡單地指定ItemsSource屬性?

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

    這將顯示您的項目,如果您的收藏品不是空的。

不管別人怎麼認爲,你的結合是正確的,因爲你是結合靜態屬性。您綁定到一個對象,您的DataContext,並將其設置爲靜態屬性的值。如果您的收藏不是null,並且在之前的值爲,則將其分配到您的組合框的DataContext,則會顯示這些項目。

我假設您的情況正在發生,您正在設置DataContext的值爲null,或者最好是空集合。

您的CheckJson方法看起來非常像DispatchTimer的事件處理程序,所以我假設您定期從網上下載元素以將它們顯示在組合框中。但是,請注意,每次您這樣做時,都會用新的ObservableCollection替換包含它們的集合!

爲了測試我的兩個假設,您只需撥打CheckJson(並確保它完全運行),然後再指定DataContext

解決您的問題,特別是因爲你的收藏是靜態的最簡單的方法,就是在_componentcollection一旦存儲的ObservableCollection(例如,在類的靜態構造函數或初始化它時,它的聲明),然後簡單地AddRemove ,或Clear必要項目。由於您的組合框將始終收聽相同的列表,因此當它的內容發生更改時會通知它。你必須:

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,因爲我建議在我的答案結尾。

+0

我同意這不是他的約束力。謝謝你的提示。 – 2013-05-08 22:09:30