2013-04-01 18 views
7

XAML için oldukça yeni ama öğrenmekten keyif alıyorum. Gerçekten uğraştığım şey, bir özelliği DataTemplate'daki bir öğeye bağlamaktır.XAML: DataTemplate'de bir özelliği bağlama

Basit bir WPF örneği oluşturdum, (umarım), sorunumu açıkla.

Ben bu örnek

benim ViewModel bir Mülke bir DataTemplate bir CheckBox arasında Visibility özelliğini bağlamak çalışıyorum. (Bu senaryoyu yalnızca öğrenme/demo için kullanma.)

Item adlı basit bir DataModel'im var, ancak bu örnekte çok az alakalı.

class Item : INotifyPropertyChanged 
{ 

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

Ve ItemViewModel adlı oldukça basit bir Görünüm Modeli.

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")); 
     } 

(Yapıcılar ve kısalık amacıyla çıkarılmıştır INotifyPropertyChanged uygulanması.) Aşağıdaki şekilde MainPage.xaml düzenlendiği

kontrol eder.

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

'Hide onay kutularını' kutusu IsCheckBoxChecked bağlıdır ve IsCheckBoxVisible güncellemek için kullanılır. Ayrıca, her şeyin işe yaradığını kanıtlamak için DataTemplate'un altında birkaç ek denetim ekledim.

Ayrıca Jeff Wilcox'un değer dönüştürücüsünü de uygulamıştım. veri şablonu içinde Checkbox değişmeden kalır, ne yazık ki, ben app çalıştırdığınızda DataTemplate fonksiyonu dışında kontroller beklendiği gibi denetleme ve 'Hide Checkbox' işaretini kaldırarak, http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

(. Teşekkür ederim) ama.

Ben başarılı olduk:

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

Ama sadece başka kontrolünü taklit ancak bir değere dayanarak kararlar çalışmıyorum.

Sunduğunuz herhangi bir yardım veya tavsiyeyi gerçekten takdir ediyorum.

Teşekkür ederiz.

+0

Visual Studio'daki hata ayıklama çıkış penceresinde herhangi bir bağlama hatası alıyor musunuz? Genelde yanlış gidenlerin iyi bir göstergesidir. – ChrisF

+0

Chris. Cevabınız için teşekkür ederiz. Çıktı pencerelerini kontrol ettiniz ve şüphelendiğiniz gibi hatalar vardı. IsCheckBoxVisible 'bulamadı'. Aşağıdaki Duncan'ın yanıtına göre düzeltildi ve şimdi iyiydi. Teşekkür ederim. – Dowse

cevap

15

Bir DataTemplate'e girdiğinizde, DataContext'iniz, veri templated nesnesidir, bu durumda Item. Böylece, DataBox'taki CheckBox'un DataContext'i, ItemViewModel'unuzun değil, Item'dur. Bunu, Item sınıfındaki bir özelliğe bağlanan <TextBlock Text="{Binding ItemName}"/> sayfanızda görebilirsiniz. IsCheckBoxVisible Bağlama, Item adresinde IsCheckBoxVisible adlı bir özellik bulmaya çalışıyor.

bu sorunu birkaç yol vardır, ama bugüne kadar en kolay bu yapmaktır: onu ve x vermek (xaml) sizin Window On

: Adı.Ör:

<Window [...blah blah...] 
     x:Name="MyWindow"> 
senin şuna benzer Bağlama değiştirin

:

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

Biz, Cilt için kaynak olarak Penceresi kullandığınız sonra (sizin ItemViewModel olması gereken kendi DataContext özelliğine bakarak, ve sonra IsCheckBoxVisible özelliğini çekerek. meraklısı bir şey istiyorsanız

Diğer bir seçenek, sizin DataContext'i başvurmak için bir proxy nesnesi kullanmaktır. this article on DataContextProxy bakınız.

+1

Duncan. Hızlı cevabınızdan dolayı teşekkür ederiz. Önerinizi denedim ve cazibe gibi çalıştı. Onay kutusu için ayrı bir etiketi ekleyeceğini düşündüm ama alas, no. Bir kez daha teşekkür ederim. Dan Wahlin'in atrisine de verdiğiniz linkte bir okuma yapacak. (Cevabınızı oylamayı denedim ama düşük itibarım benim bunu yapmamı engelliyor.) – Dowse

+0

Sevindim, yardımcı olabilirim! :-) Tamamen alakalı değil, sadece bir kenara, yorumunuza: bir öğenin DataContext'inin (Pencere veya başka bir kök hariç) manuel olarak ayarlanması, çok dikkatli olmak istediğiniz bir şeydir ve çoğu zaman sizin yanlış bir şey yapıyorsun. Senin girişimin 'satırında olduğunu hayal ediyorum: eğer öyleyse, işe yaramasın nedeni, xaml öğesinde ItemViewModel'i tanımladığınız zamandır. * Bir, farklı bir örneğiniz var. Bunu aşabilirsin, ama tarif ettiğim çözüm daha iyi. –