2014-11-02 76 views
0

我有一個用戶控件以下元素,作爲默認Grid的唯一子:爲什麼我的ObservableCollection不可見?

<ListView ItemsSource="{Binding LogCollection}" Name="LogView"> 
    <ListView.View> 
     <GridView> 
      <GridView.Columns> 
       <GridViewColumn DisplayMemberBinding="{Binding Level}" Header="Level"/> 
       <GridViewColumn DisplayMemberBinding="{Binding FormattedMessage}" Width="500" Header="Message"/> 
       <GridViewColumn DisplayMemberBinding="{Binding Exception}" Header="Exception"/> 
      </GridView.Columns> 
     </GridView> 
    </ListView.View> 
</ListView> 

在後面的代碼,我轉運的定製NLOG Target以下事件。我只是處理它,因爲給我一個例子,總的WPF noob,但它似乎沒問題。

private void EventReceived(LogEventInfo message) 
{ 
    Dispatcher.Invoke(() => 
     { 
      if (LogCollection.Count >= 50) 
      { 
       LogCollection.RemoveAt(LogCollection.Count - 1); 
      } 
      LogCollection.Add(message); 
     }); 
} 

事件觸發的罰款,並在Add呼叫到達時,我通過代碼。當我在執行時在XAML視圖中將鼠標移到LogCollection上時,我看到一個「Count = 1」,此時ListView`仍然幸福地意識不到它應該顯示我一個日誌事件。

OK,OK,背後爲我的用戶控件刪節代碼:

public partial class LoggingControl : UserControl 
{ 
    public ObservableCollection<LogEventInfo> LogCollection { get; set; } 
    public LoggingControl() 
    { 
     LogCollection = new ObservableCollection<LogEventInfo>(); 
     InitializeComponent(); 

     foreach (Target target in LogManager.Configuration.AllTargets) 
     { 
      var memoryEventTarget = target as MemoryEventTarget; 
      if (memoryEventTarget != null) 
      { 
       memoryEventTarget.EventReceived += EventReceived; 
      } 
     } 
    } 

    private void EventReceived(LogEventInfo message) 
    { 
     Dispatcher.BeginInvoke(new Action(() => 
        { 
         LogCollection.Add(message); 
        })); 
    } 
} 
+0

雙向綁定與此場景沒有任何關係。 – 2014-11-02 08:53:27

+0

@MilanNankov我同意,但仍然給它一個bash無論如何。我在列表中沒有做任何事情,必須將其綁定回集合,它只能讀取它。 – ProfK 2014-11-02 08:55:37

+0

順便說一句,@米蘭南科夫和我的評論只是在另一個背景下,因爲刪除,建議TwoWay評論。 – ProfK 2014-11-02 09:01:00

回答

1

正如在註釋中提到的那樣,綁定ListView.ItemsSource綁定的上下文似乎是錯誤的。 DataContext。在你的情況設置DataContext手動可以解決這個問題

this.DataContext = this; 

但是這需要創建LogCollection後與屬性本身不會引發INotifyPropertyChanged.PropertyChanged事件做。

並回答爲什麼DataContext默認情況下未設置爲自身的原因是因爲DataContext在整個可視化樹中都被繼承。因此,UserControl與其他FrameworkElement一樣,默認情況下會從其放置的元素繼承其DataContext

值得注意的另一件事是,只能有一個DataContext值。它將從視覺樹繼承或在您的UserControl中手動設置。您可以使用繼承的上下文,並通過使用RelativeSourceElementName綁定來綁定到UserControl屬性。

<UserControl ... x:Name="myUserControl"> 
    <!-- ---> 
    <ListView ItemsSource="{Binding LogCollection, ElementName=myUserControl}" Name="LogView"> 
+1

是的,謝謝,我剛剛意識到它在UserControl中是非常有意義的,我必須將dc設置爲Self,否則它將繼承父項。對更多顯式綁定的額外提示+1。 – ProfK 2014-11-02 10:22:12

0

你肯定LogCollection你實際上添加的項目是你網格綁定到一個?我已經創建了一個具有代碼的示例應用程序,但按預期工作?也許你需要發佈更多的代碼。

Here is my sample application

也許你的ItemsSource綁定現在可以工作了。你在控制檯中看到任何綁定錯誤嗎?類似於「BindingExpression path error:'LogCollection'property not found on'object'」

+0

是的,只有一個'LogCollection'。在輸出窗口中看不到任何錯誤,只有日誌消息,因爲我的自定義日誌目標也在其他地方寫入。當我初始化時,我會嘗試直接添加到集合中,以查看它是否獲取了初始內容。然後,我會檢查您的示例,然後進行一些大規模編輯以發佈更多代碼,而不會亂扔這個頁面太多。 – ProfK 2014-11-02 09:28:18

+0

由於您的DataContext設置不正確,您的綁定可能不起作用 - 您的LogCollection不是您的DataContext的推理。你說過,LogCollection屬性是在你有GridView的控件上定義的。如果是這種情況,只需在控件的構造器中將控件本身設置爲DataContext即可。 例如,在控制器的構造函數中 - > this.DataContext = this; – 2014-11-02 09:40:05

+0

我曾說'LogCollection'是我用戶控件的屬性,而不是我的用戶控件或其'Grid'中的任何東西。我很好地說過,ListView是我用戶控件上唯一的子控件。 – ProfK 2014-11-02 09:42:36