2017-02-24 22 views
0

WPFプロジェクトでは、多角形を定義するユーザーコントロール(Valve.xaml)があります。ユーザーコントロールで要素のスタイルを動的に設定する方法

<Grid> 
    <Polygon Name="pValve" Points="0,50 0,20 50,50 50,20" Style="{StaticResource Valve_Open}"/> 
</Grid> 

私はそのようなウィンドウのXAML(FFG.xaml)ファイルにバルブのユーザーコントロールを表示しています:私はクラスFFG_ViewModel.csにFFG.xamlのDataContextの設定しています

<Window 
    <!-- removed other namespaces for brevity --> 
    xmlns:cl="clr-namespace:FFG.Controls;assembly=PID.Controls"> 
    <Grid> 
     <cl:Valve x:Name="valve201A"></cl:Valve> 
    </Grid> 
</Window> 

、 Valve_Modelクラスのインスタンスが含まれています。 Valve_Modelは基本的にFFG.xamlのウィンドウに描画されるバルブを表します。

public class FFG_ViewModel : ViewModelBase { 

    public Valve_Model Valve201A { get; set; } 

    // There are other properties and methods, but I've removed them for brevity also 

} 

はここValve_Modelクラスです:

public class Valve_Model INotifyPropertyChanged { 

     public event PropertyChangedEventHandler PropertyChanged; 

     private bool _isValveOpen { get; set; } 
     public bool IsValveOpen { 
      get { 
       return _isValveOpen; 
      } 
      set { 
       _isValveOpen = value; 
       OnPropertyChanged("IsValveOpen"); 
      } 
     } 

     #region INotifyPropertyChanged 
     protected virtual void OnPropertyChanged(string propertyName) { 
      PropertyChangedEventHandler handler = this.PropertyChanged; 
      if (handler != null) { 
       var e = new PropertyChangedEventArgs(propertyName); 
       handler(this, e); 
      } 
     } 
     #endregion 

    } 

QUESTION: ときIsValveOpenプロパティの変更を変更するValve.xamlでStyleプロパティのためである私は何をしたいです。

バルブが開いているのであれば、それは次のようになります。

<Polygon Name="pValve" Points="0,50 0,20 50,50 50,20" Style="{StaticResource Valve_Open}"/> 

とプロパティをfalseに変更されたとき、私はポリゴンのスタイルに変更する必要があります

<Polygon Name="pValve" Points="0,50 0,20 50,50 50,20" Style="{StaticResource Valve_Closed}"/> 

これを正確に実装するにはどうすればよいですか?

答えて

1

あなたはIMultiValueConverterを使用することができます。

まず、ユースケースを簡略化しましょう。基本的に、Stylesをスワップしたいのは、与えられた状態オブジェクトに基づいています。これはToggleButtonで表します。 UserControlのすべてをラップしているという事実も、基本的な概念には影響しません。

デモ:

  • 新鮮なプロジェクト
  • ConverterWindowと状態を給餌当社Resources
  • の宣言を開始します。

MainWindow.xaml

<Window 

    ... 

    > 
    <Window.Resources> 
     <local:ToStyleConverter x:Key="ToStyleConverter"/> 
     <Style x:Key="Valve_Open" TargetType="{x:Type Polygon}"> 
      <Setter Property="Fill" Value="Red"/> 
     </Style> 
     <Style x:Key="Valve_Closed" TargetType="{x:Type Polygon}"> 
      <Setter Property="Fill" Value="Green"/> 
     </Style> 
    </Window.Resources> 
    <DockPanel> 
     <ToggleButton x:Name="butt" DockPanel.Dock="Bottom">Switch</ToggleButton> 
     <Polygon Name="pValve" Points="0,50 0,20 50,50 50,20" Stretch="Uniform"> 
      <Polygon.Style> 
       <MultiBinding Converter="{StaticResource ToStyleConverter}"> 
        <Binding RelativeSource="{RelativeSource FindAncestor, 
               AncestorType={x:Type Window}}"/> 
        <Binding ElementName="butt" Path="IsChecked"/> 
       </MultiBinding> 
      </Polygon.Style> 
     </Polygon> 
    </DockPanel> 
</Window> 

MainWindow.xaml。任意の特定のユースケースへの変更CS

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 
} 

public class ToStyleConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (values[0] is Window) 
     { 
      Window win = (Window)values[0]; 
      if ((bool)values[1]) 
       return win.FindResource("Valve_Open"); 
      if (!(bool)values[1]) 
       return win.FindResource("Valve_Closed"); 
     } 
     return DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object values, Type[] targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

手段:

  • はに状態を追加する第二の結合を使用しResources(スタイル)を保持Control
  • に結合relativesourceポインティングConverter(DP/INPC)
  • ロジック
+0

これはそれでした。助けてくれてありがとう! – Jagd

0

DataTriggerControlTemplateに(私が知っている限り)使用することができます。これら二つは、あなたのスタイルであると仮定:

<Window.Resources> 
    <Style TargetType="Polygon" x:Key="Valve_Open"> 
     <Setter Property="Fill" Value="Red"/> 
    </Style> 
    <Style TargetType="Polygon" x:Key="Valve_Close"> 
     <Setter Property="Fill" Value="Green"/> 
    </Style> 
</Window.Resources> 

あなたがリソースにこのスタイルを追加する必要があります

<Style x:Key="changeStyle" TargetType="Control"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Control"> 
        <Grid> 
         <Polygon Name="pValve" Points="0,50 0,20 50,50 50,20" Style="{StaticResource Valve_Open}" /> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <DataTrigger Binding="{Binding Valve201A.IsValveOpen}" Value="true"> 
          <Setter TargetName="pValve" Property="Style" Value="{StaticResource Valve_Close}" /> 
         </DataTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

をし、あなたの意見でそれらを使用します。

<Control DataContext="{Binding}" Style="{StaticResource changeStyle}" /> 
+0

これは単純な組成物のための巧妙なトリックであるが、それは(後ろコード)に延びるための可能性を提供しないと'UserControl'から予期されるカプセル化(ライブラリ)です。 – bab7lon

0

実際のStyleプロパティを新しい値に設定する代わりにIsValveOpenソースプロパティの値に基づいてPolygonのプロパティを変更するスタイル自体にDataTriggerを追加することができます。

Valve.xaml:

<Grid> 
    <Polygon Name="pValve" Points="0,50 0,20 50,50 50,20"> 
     <Polygon.Style> 
      <Style TargetType="Polygon"> 
       <!-- Copy the setters from the Valve_Closed style here --> 
       <Setter Property="Fill" Value="Red" /> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding IsValveOpen}" Value="True"> 
         <!-- Copy the setters from the Valve_Open style here --> 
         <Setter Property="Fill" Value="Red" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Polygon.Style> 
    </Polygon> 
</Grid> 

FFG.xaml:

<Grid> 
    <cl:Valve x:Name="valve201A" DataContext="{Binding Valve201A}" /> 
</Grid> 
関連する問題