2011-04-29 19 views
5

我在學習如何使用WPF綁定和MVVM體系結構。我遇到了依賴屬性的一些麻煩。我試圖通過將它綁定到DataContext中的DependencyProperty來控制視圖上項目的可見性,但它不起作用。無論我如何在下面的視圖模型的構造函數中設置GridVisible值,在運行代碼時它總是顯示爲可見。WPF數據綁定體系結構問題

任何人都可以看到我要去哪裏錯了嗎?

C#代碼(視圖模型):

public class MyViewModel : DependencyObject 
{ 
    public MyViewModel() 
    { 
     GridVisible = false; 
    } 

    public static readonly DependencyProperty GridVisibleProperty = 
    DependencyProperty.Register(
     "GridVisible", 
     typeof(bool), 
     typeof(MyViewModel), 
     new PropertyMetadata(false, 
       new PropertyChangedCallback(GridVisibleChangedCallback))); 

    public bool GridVisible 
    { 
     get { return (bool)GetValue(GridVisibleProperty); } 
     set { SetValue(GridVisibleProperty, value); } 
    } 

    protected static void GridVisibleChangedCallback(
     DependencyObject source, 
     DependencyPropertyChangedEventArgs e) 
    { 
     // Do other stuff in response to the data change. 
    } 
} 

XAML代碼(查看):

<UserControl ... > 

    <UserControl.Resources> 
     <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> 
    </UserControl.Resources> 

    <UserControl.DataContext> 
     <local:MyViewModel x:Name="myViewModel" /> 
    </UserControl.DataContext> 

    <Grid x:Name="_myGrid" 
     Visibility="{Binding Path=GridVisible, 
      ElementName=myViewModel, 
      Converter={StaticResource BoolToVisConverter}}"> 

     <!-- Other elements in here --> 

    </Grid> 

</UserControl> 

我在幾個教程在網上看了,似乎像我正確地遵循我在那裏找到的內容。有任何想法嗎?謝謝!

回答

2

從您的綁定中取出ElementName,看起來不正確。 將其更改爲:

<Grid x:Name="_myGrid" 
     Visibility="{Binding Path=GridVisible, 
      Converter={StaticResource BoolToVisConverter}}"> 
+0

其實我把你的代碼複製出來,發現它與包含和不包含ElementName的綁定一起工作。你在使用usercontrol(即一個窗口或其他用戶控件)?也許在那裏有什麼問題(你沒有包含代碼)。 – thornhill 2011-04-29 21:51:28

+0

我刪除了ElementName,它仍然不起作用。看起來你是對的 - 它可能與我的代碼的另一部分有關,而不是上面發佈的消毒版本。不幸的是,我不能發佈實際的代碼,因爲它是爲了工作。 – RobotNerd 2011-04-29 21:55:34

+0

在這種情況下,當您運行應用程序並打開包含此用戶控件的窗口時,請在VisualStudio的「輸出」窗口中查找與此文本類似的任何錯誤。 「BindingExpression path error:'GridVisible'property not found on 'object ......「 該消息的內容可能會幫助您進一步調試。 抱歉,我無法幫助你更多。祝你好運。 – thornhill 2011-04-30 08:06:54

0

設置視圖模型作爲DataContext的的一點是使容易相對綁定,所有綁定在這裏你只指定Path採取的DataContext作爲源這是整個用戶控件繼承(除非它是例如在ItemsControl的模板項目中設置)

因此,一旦在UserControl上設置DataContext,通常在綁定到VM時不指定任何源。 (來源是ElementNameRelativeSourceSource

另外我個人不會作出的ViewModels從DependencyObject繼承因爲這引入線程的親和性,也DependencyProperties的點是使稀疏數據結構通過不產生在所有的不必要的字段更有效他們(ViewModels通常與稀疏相反)。

+3

'INotifyPropertyChanged'是'DependencyObject'的替代品 - 大多數視圖模型使用這種替代依賴項屬性。 – 2011-04-29 22:26:23

1

讓您的ViewModel實現INotifyPropertyChanged而不是繼承DependencyObject。 實現接口並從屬性的setter中引發PropertyChanged。

private bool gridVisible; 

    public bool GridVisible 
    { 
     get { return gridVisible; } 
     set 
     { 
      gridVisible = value; 
      OnPropertyChanged("GridVisible"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
+1

您不需要使用ElementName在您的XAML中引用您的虛擬機,也不需要命名虛擬機。將它分配給usercontrol.DataContext時,它將成爲用戶控件的所有子項的默認綁定源。 – 2011-04-30 08:16:27