2013-04-01 97 views
7

我對XAML相當陌生,但喜歡學習它。我真正努力的是將一個屬性綁定到DataTemplate中的一個元素。XAML:綁定DataTemplate中的屬性

我已經創建了一個簡單的WPF示例來(希望)解釋我的問題。

我這個例子我試圖將中CheckBoxVisibility屬性綁定到我的viewmodel中的屬性。 (純粹用於學習/演示使用此場景。)

我有一個簡單的DataModel,名稱爲Item,但在此示例中沒有多大關聯。

class Item : INotifyPropertyChanged 
{ 

    // Fields... 
    private bool _IsRequired; 
    private string _ItemName; 

和一個相當簡單的名爲ItemViewModel的視圖模型。

class ItemViewModel : INotifyPropertyChanged 
{ 
    private ObservableCollection<Item> _Items; 
    private bool _IsCheckBoxChecked; 
    private bool _IsCheckBoxVisible; 

    public ObservableCollection<Item> Items 
    { 
     get { return _Items; } 
     set { _Items = value; } 
    } 


    public bool IsCheckBoxChecked 
    { 
     get { return _IsCheckBoxChecked; } 
     set 
     { 
      if (_IsCheckBoxChecked == value) 
       return; 
      _IsCheckBoxChecked = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxChecked")); 
       PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible")); 
      } 
     } 
    } 


    public bool IsCheckBoxVisible 
    { 
     get { return !_IsCheckBoxChecked; } 
     set 
     { 
      if (_IsCheckBoxVisible == value) 
       return; 
      _IsCheckBoxVisible = value; 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible")); 
     } 

(構造器和INotifyPropertyChanged實施不再贅述。)在MainPage.xaml中佈置如下

控件。

<Window.Resources> 
    <local:VisibilityConverter x:Key="VisibilityConverter"/> 
</Window.Resources> 

<Window.DataContext> 
    <local:ItemViewModel/> 
</Window.DataContext> 

<Grid> 
    <StackPanel> 
     <CheckBox x:Name="checkBox" Content="Hide CheckBoxes" FontSize="14" IsChecked="{Binding IsCheckBoxChecked, Mode=TwoWay}" /> 
     <ListView ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch" > 
      <ListView.ItemTemplate > 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="Auto"/> 
        </Grid.ColumnDefinitions> 
        <TextBlock Text="{Binding ItemName}"/> 
         <CheckBox Grid.Column="1" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}" > 
          <CheckBox.DataContext> 
           <local:ItemViewModel/> 
          </CheckBox.DataContext> 
         </CheckBox> 
        </Grid> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
     <StackPanel Orientation="Horizontal" Margin="4,4,0,0"> 
     <TextBlock Text="IsCheckBoxVisible:"/> 
      <TextBlock Text="{Binding IsCheckBoxVisible}" Margin="4,0,0,0" FontWeight="Bold" /> 
     </StackPanel > 
     <Button Content="Button" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}" Margin="4,4,4,4"/> 
    </StackPanel> 

</Grid> 

在「隱藏複選框」複選框被綁定到IsCheckBoxChecked和用於更新IsCheckBoxVisible。我還在DataTemplate下面添加了一些額外的控件來證明(對我自己而言)一切正常。)

我也實現了Jeff Wilcox的值轉換器。 (謝謝。)http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

當我運行應用程序,檢查和取消選中「隱藏複選框」,如預期的那樣DataTemplate功能外控,但是,唉,數據模板內Checkbox保持不變。

我曾與成功:

IsVisible="{Binding IsChecked, Converter={StaticResource VisibilityConverter}, ElementName=checkBox}" 

但我不只是試圖模仿另一個控制,但要根據價值決定。

我會真正感謝您可以提供的任何幫助或建議。

謝謝。

+0

在Visual Studio的調試輸出窗口中是否有任何綁定錯誤?他們通常很好地指出發生了什麼問題。 – ChrisF

+0

克里斯。感謝您的迴應。檢查輸出窗口,並且,如您所懷疑的那樣,出現錯誤。它無法'找到'IsCheckBoxVisible。根據Duncan的回覆,下面的應用修復,現在一切正常。謝謝。 – Dowse

回答

15

當您在DataTemplate中時,DataContext是數據模板對象,在本例中爲Item。因此,DataTemplate中CheckBox的DataContext是Item,而不是你的ItemViewModel。你可以看到你的<TextBlock Text="{Binding ItemName}"/>,它綁定到Item類的一個屬性。綁定到IsCheckBoxVisible正試圖在Item上找到名爲IsCheckBoxVisible的屬性。

有一對夫婦的解決這個辦法,但截至目前爲止最簡單的就是要做到這一點:

你的窗口(在XAML),給它和X:名稱。例如:

<Window [...blah blah...] 
     x:Name="MyWindow"> 

更改您的結合,看起來像這樣:

<CheckBox Grid.Column="1" 
      Visibility="{Binding DataContext.IsCheckBoxVisible, ElementName=MyWindow, Converter={StaticResource VisibilityConverter}}"> 

我們使用窗口作爲源綁定,然後看着它的DataContext屬性(這應該是你的ItemViewModel,然後脫下IsCheckBoxVisible財產。

另一種選擇,如果你想要的東西票友,是使用代理對象引用您的DataContext。見this article on DataContextProxy

+1

鄧肯。感謝您的及時答覆。我已經嘗試了你的建議,它的功能就像一個魅力。我認爲添加一個單獨的標籤的複選框將工作,但唉,不。再次感謝你。在給你提供的鏈接中也會給Dan Wahlin的atricle一個閱讀。 (我試着投票回答你的答案,但是我的低聲譽阻止我這樣做。) – Dowse

+0

很高興我能幫上忙! :-)這並不完全相關,但從您的評論中可以看出:手動設置元素的DataContext(除了Window或其他根目錄)是您想要非常小心的事情,並且通常表明您'做錯了事。我想象你的嘗試是沿着'行的:如果是這樣,它不起作用的原因是當你在xaml中定義ItemViewModel時,就像* *一個,所以你會有一個不同的實例。你可以解決這個問題,但我描述的解決方案更好。 –

相關問題