2012-08-14 160 views
0

我是Silverlight新手,我無法做出簡單的Silverlight綁定示例工作!Silverlight綁定不起作用

我需要製作一個視圖模型,該視圖模型顯示列表中正在加載的文檔的數量。

我做了一個基類,即實現INotifyPropertyChanged:

public abstract class BaseViewModel : INotifyPropertyChanged { 

    protected BaseViewModel() {} 


    #region INotifyPropertyChanged Members 

    protected void OnPropertyChanged(string propertyName) { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

我做了一個子級,即有 「CountDocs」 屬性:

public class DocumentViewModel : BaseViewModel { 

    public DocumentViewModel() { 
    ... 
    } 

... 

    public int CountDocs { 
     get { return countDocs; } 
     set { 
      if (countDocs != value) { 
       countDocs = value; 
       OnPropertyChanged("CountDocs"); 
      } 
     } 
    } 

    public int countDocs; 

} 

我DocumentViewModel.xaml與以下內容:

<UserControl 
... 
xmlns:vm="clr-namespace: ... .ViewModels" > 
... 
<UserControl.Resources> 
    <vm:DocumentViewModel x:Key="viewModel"/> 
</UserControl.Resources> 
... 
<TextBlock x:Name="CounterTextBlock" Text="{Binding Source={StaticResource viewModel}, Path=CountDocs}"></TextBlock> 

那是我提到的我的子類的命名空間,我做了一個資源我的子類與關鍵「viewModel」,我輸入文本塊的綁定,這個對象的屬性「CountDocs」。

問題是CountDocs屬性只填充TextBlock一次:on load。但後來我設置了CountDocs,並且它不填充TextBlock。

我試圖使用綁定的Mode屬性來使用DataContext,但我仍然無法使其工作。

綁定有什麼問題嗎?如何更改我的對象的CountDocs屬性時ViewModel更新?

感謝

+0

你有沒有檢查它是否通過'處理程序!= null'條件並引發事件? – Zabavsky 2012-08-14 08:57:50

+0

VS中的「輸出」窗口會顯示綁定失敗。我不得不看到更多的代碼,但是一個可能的遠程診斷是你無意中創建了多個「DocumentViewModel」實例。 – herzmeister 2012-08-14 09:00:33

+0

你是否試圖在另一個線程上設置新值?任何UI屬性更新都必須在UI線程上進行(例如,您將需要使用調度程序將它們傳遞給UI線程)。如果是這樣,可能的答案在下面給你。 – 2012-08-14 09:17:09

回答

0

好,既然你在你的XAML中創建了你的ViewModel實例,你需要訪問和使用該ViewModel。

如果您有另一個實例,那個實例將不會更新您的綁定。只有在您的資源中創建的實例纔會被使用。

現在你說你設置CountDocs屬性,但我沒有看到任何代碼。無論你如何做,都必須使用資源中的ViewModel實例。

這就是爲什麼我喜歡在我的視圖的構造函數中實例化我的視圖模型並保留對它的引用。另外,除非您計劃將許多數據源附加到綁定,否則可以簡單地將LayoutRoot.DataContext設置爲ViewModel實例,並在綁定中移除Source屬性。

ViewModelBase _vm = null;
public MyView()
{
_vm = new DocumentViewModel();
this.LayoutRoot.DataContext = _vm;
}

在XAML中, <TextBlock x:Name="CounterTextBlock" Text="{Binding CountDocs}"></TextBlock>

+0

在他給出的示例中,他在XAML中實例化了VM,並直接並正確地將其引用爲綁定源:'Source = {StaticResource viewModel}'。 – herzmeister 2012-08-14 13:39:44

0

如果我明白你的問題的細節,你可能會在後臺線程更新UI綁定值(如文檔加載)。

您需要在UI線程上進行此操作,否則更改將不可見。在我們的WPF應用之一中,隨機更新正在消失,直到我們意識到這一點。

我們在我們的Silverlight(和WPF)應用程序中執行了很多多線程操作,所以爲了避免這個問題,我們在基類中實現了我們的通知幫助程序(其他東西被刪除)。它分派主UI線程上的所有通知消息。試一試:

public class ViewModelBase : INotifyPropertyChanged 
{ 
    protected delegate void OnUiThreadDelegate(); 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void SendPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
     { 
      // Ensure property change is on the UI thread 
      this.OnUiThread(() => this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName))); 
     } 
    } 

    protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate) 
    { 
     // Are we on the Dispatcher thread ? 
     if (Deployment.Current.Dispatcher.CheckAccess()) 
     { 
      onUiThreadDelegate(); 
     } 
     else 
     { 
      // We are not on the UI Dispatcher thread so invoke the call on it. 
      Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate); 
     } 
    } 
} 
+0

它沒有幫助,不幸... – Roux 2012-08-14 10:06:25

+0

@Roux:你可以發佈你用來更新財產的代碼嗎? – 2012-08-14 10:38:34

0

正如我們在評論你的問題發現了,你有你的視圖模型實例化兩次,在這本來就不是綁定到一個更改的屬性值風景。

這怎麼可能?您要麼使用自動將ViewModels連接到視圖的MVVM框架,要麼會發生在代碼中您不知道的地方。在構造函數中放置一個斷點,並在它命中時分析Visual Studio中的調用堆棧。