2016-04-01 19 views
2

Çalıştığım uygulamada, izlediğim birkaç öğe var. Her öğenin birkaç durumu vardır (açık, kapalı, değiştir). Devletler, modele kaydedilir ve pencerenin DataContext'i buna ayarlanır. Her düğme DataContext, SortableBindingList öğesinde tek bir öğeye ayarlandı. XAML'de Düğme ve DataTrigerrs içinde Kontrol Şablonu oluşturdum. Bununla birlikte, bazen yalnızca ilk düğmeler için öğe gösterilir, bazen sadece ilk üç düğme için (DataTrigger içine hangi içeriğe girdiğime bağlı olarak). Snoop'ta kontrol ettiğimde, üç düğmenin de doğru DataContext setine sahip olduğunu ve hiçbir bağlama hatası olmadığını görüyorum. Her düğmenin 'servertate' özelliğinin değerine bağlı olarak içeriğini göstermesini beklerim, ancak bu gerçekleşmez. Neyi yanlış yapıyorum?Düğme denetim şablonu ve DataTriggers

Kontrol Şablon Window.Resources gider:

<ControlTemplate x:Key="buttonTemplate" TargetType="Button" > 
      <Border BorderThickness="1" 
        BorderBrush="Gray" 
        Margin="2" 
        Width="40" Height="35" 
        > 
       <Border.Background> 
        <SolidColorBrush Color="Brown" /> 
       </Border.Background> 
       <ContentPresenter /> 
      </Border> 

      <ControlTemplate.Triggers> 
       <DataTrigger Binding="{Binding serverstate}" Value="0"> 
        <Setter Property="Content"> 
         <Setter.Value> 
          <TextBlock Name="a1" Text="OFF" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" /> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding serverstate}" Value="1"> 
        <Setter Property="Content"> 
         <Setter.Value> 
          <TextBlock Name="a2" Text="CHNG" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" /> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding serverstate}" Value="2"> 
        <Setter Property="Content"> 
         <Setter.Value> 
          <TextBlock Name="a3" Text="ON" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" /> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 

Düğmeler:

<Button Name="state1" 
     DataContext="{Binding ActiveServers[0]}" 
     Template="{StaticResource buttonTemplate}" 
     /> 

<Button Name="state2" 
     DataContext="{Binding ActiveServers[1]}" 
     Template="{StaticResource buttonTemplate}" 
     /> 

<Button Name="state3" 
     DataContext="{Binding ActiveServers[2]}" 
     Template="{StaticResource buttonTemplate}" 
     /> 

<Button Name="state4" 
     DataContext="{Binding ActiveServers[3]}" 
     Template="{StaticResource buttonTemplate}" 
     /> 

<Button Name="state5" 
     DataContext="{Binding ActiveServers[4]}" 
     Template="{StaticResource buttonTemplate}" 
     /> 

Bu düğmeler penceresinden nasıl göründüğünü:

How buttons in window show up

Bildirimi nasıl düğmesi 4 ve 5, datacontext'te özellik değerini tamamen yok sayar.

Modeli:

public class Model : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public Model() 
    { 

    } 

    private SortableBindingList<Server> _activeServers; 
    public SortableBindingList<Server> ActiveServers 
    { 
     get { 
      if (_activeServers == null) 
      { 
       _activeServers = new SortableBindingList<Server>(); 
      } 

      return _activeServers; 
     } 
     set 
     { 
      _activeServers = value; 
      OnPropertyChanged("serverList"); 
     } 
    } 

    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
+0

"TextBlocks" içindeki "Text" özelliği için 'DataTrigger 'yerine' ValueConverter' kullanılmasını önerebilirim. – bars222

+0

Ur ilk 3 düğme düzgün gösteriyor "ActiveServers" koleksiyonunun bazı bilinmeyen 'servertate' değeri içerdiği anlamına gelir. – AnjumSKhan

+0

@AnjumSkhan Hayır, koleksiyonumda her şey yolunda. Sorun, aşağıda kullanıcı bar222 tarafından başarıyla çözüldü! – VladacusB

cevap

2

Sorunun düşünüyorum iki düğme Content aynı kullanabilirsiniz cann't söyledi. Dolayısıyla, her tetikleme değeri için Content her tür bir kez görüntülenir. Bunu ContentTemplate kullanarak önleyebilirsiniz. Yani kod böyle görünmelidir (diğer DataTriggers için aynı). Daha sonra daha karmaşık hale getirmek için DataTemplates değiştirmenize izin verir.

<DataTrigger Binding="{Binding serverstate}" Value="2"> 
    <Setter Property="ContentTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <TextBlock Text="ON" VerticalAlignment="Center" 
          HorizontalAlignment="Center" Foreground="White" /> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</DataTrigger> 
+0

Teşekkürler, bu sorunu çözdü! :) Ancak, ContentTemplate ile İçerik arasındaki farkı anlamıyorum? Ayrıca DataTemplate'i yalnızca birden fazla öğe örneğine sahip olduğundan ItemsControls için kullanabileceğimi düşündüm. Beni yeni başlayanların bunu anlayabileceği herhangi bir kaynağa işaret edebilir misiniz? – VladacusB

+0

Wpf Unleashed iyi bir kitaptır, ayrıca msdn ve codeproject makaleleri iyidir. Andrew troelsen tarafından C# ve .net platformu yeni başlayanlar için iyi bir kitap. Soruyu çözülmüş olarak işaretlemek için cevabı kabul edebilirsiniz. – bars222

+0

Evet WPF Unleashed harika bir kitap. Cevabınızı çözülmüş olarak kabul ettiniz. – VladacusB

0

deneyin Content özelliğini değiştirmek, ancak yeni TextBlock yaratmak değil:

<ControlTemplate.Triggers> 
      <DataTrigger Binding="{Binding serverstate}" Value="0"> 
       <Setter Property="Content" Value="OFF"></Setter> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding serverstate}" Value="1"> 
       <Setter Property="Content" Value="CHNG"></Setter> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding serverstate}" Value="2"> 
       <Setter Property="Content" Value="ON"></Setter> 
      </DataTrigger> 
     </ControlTemplate.Triggers> 
+0

Teşekkürler, ancak önceden tanımlanmış belirli denetim örneklerini kullanamıyorum. Bu şablonun içindeki herhangi bir genel İçerik türünü kullanmam gerekiyor. Örneğin, görüntü, tuval veya başka bir düzen (giriş veya yığınpan gibi) olabilir. – VladacusB