2016-04-11 7 views
1

同じタイプのすべてのコントロールにXAMLの動作を取り付けこれと同じ設定でTextBoxを実行します。コードを繰り返すのではなく(私が現在行っているように)、そのトリガーをタイプ{x:Type TextBox}のすべてのコントロールに付加したいと考えています。は、私はそれがそうのような<code>TextBox</code>の<code>GotFocus</code>イベントにアタッチされている<code>InvokeCommandAction</code>を持って

<UserControl.Resources> 
    <Style TargetType="TextBlock"> 
     <Setter Property="Padding" Value="5,0,0,0" /> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
    </Style> 
</UserControl.Resources> 

残念ながら、このTriggersのために動作しません:

添付プロパティの「トリガー」のみ適用することができ、これはのように

通常、私は、Resourcesセクションのプロパティを設定しますDependencyObjectから派生した型に変換します。

理想的には、私はこのような何かをしたいと思います:私は、ちょうどメッセージを指定するには、各TextBoxTagプロパティを設定する必要が

<UserControl.Resources> 
    <Style TargetType="{x:Type TextBox}"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="GotFocus"> 
       <i:InvokeCommandAction Command="{Binding GotFocusCommand}" CommandParameter="{Binding Tag}" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </Style> 
</UserControl.Resources> 

が表示されます。正しい軌道にいるのですか? ControlTemplateなどを使用するように変更する必要がありますか?私はここに同様の質問見てきました

EDIT:

<UserControl.Resources> 
    <TextBox x:Key="TextBoxWithTag"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="GotFocus"> 
       <i:InvokeCommandAction Command="{Binding GotFocusCommand}" CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </TextBox> 
</UserControl.Resources> 

その後のようなコントロールに割り当てる:その質問に対しての答えを読んだ後Interaction Triggers in Style in ResourceDictionary WPF

は、私は次のことを試してみましたso:

<ContentControl Grid.Row="0" 
       Grid.Column="1" 
       Width="40" 
       HorizontalAlignment="Right" 
       Content="{StaticResource TextBoxWithTag}" 
       Tag="test tag" /> 

これもまだ不満、動作しません:

添付プロパティを「トリガは」のみ「のDependencyObject」に由来しているタイプに適用することができます。

EDIT 2

ここGotFocusCommand情報です。 TextBlockがバインドされたstringの値を設定します。

これは私のViewModelである。そして、

private ICommand _gotFocusCommand; 
public ICommand GotFocusCommand 
{ 
    get 
    { 
     if (_gotFocusCommand == null) 
     { 
      _gotFocusCommand = new DelegateCommand<string>(TextBoxGotFocus); 
     } 
     return _gotFocusCommand; 
    } 
} 

private void TextBoxGotFocus(string infoText) 
{ 
    CardInfoText = infoText; 
} 

XAML:

<TextBlock Grid.Row="2" 
      Grid.Column="0" 
      Grid.ColumnSpan="2" 
      HorizontalAlignment="Center" 
      Text="{Binding CardInfoText}" /> 
+0

どのようにそのメッセージを表示しますか?そうではなく、何を表示する必要がありますか?ターゲットTextBoxへの参照で十分ですか? – Evk

+0

'ViewModel'に' DelegateCommand'を 'GotFocusCommand'と呼んでいます。これは、' TextBlock'をバインドした値を設定します。私はそれを質問にも追加します。 –

答えて

6

あなたがやりたいことには、いくつかの方法があります。一例:

public static class UIBehaviors { 
    public static readonly DependencyProperty AttachedTriggersProperty = DependencyProperty.RegisterAttached(
     "AttachedTriggers", typeof (EventTriggerCollection), typeof (UIBehaviors), new PropertyMetadata(null, OnAttachedTriggersChanged)); 

    private static void OnAttachedTriggersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
     var triggers = Interaction.GetTriggers(d); 
     if (e.OldValue != null) { 
      foreach (var trigger in (EventTriggerCollection) e.OldValue) { 
       triggers.Remove(trigger); 
      } 
     } 
     if (e.NewValue != null) { 
      foreach (var trigger in (EventTriggerCollection) e.NewValue) { 
       triggers.Add(trigger); 
      } 
     } 
    } 

    public static void SetAttachedTriggers(DependencyObject element, EventTriggerCollection value) { 
     element.SetValue(AttachedTriggersProperty, value); 
    } 

    public static EventTriggerCollection GetAttachedTriggers(DependencyObject element) { 
     return (EventTriggerCollection) element.GetValue(AttachedTriggersProperty);    
    } 
} 

public class EventTriggerCollection : Collection<EventTrigger> { 

} 

ここでは、InteractivityアセンブリのEventTriggerのセットを受け入れる添付プロパティを宣言します。このプロパティが設定されている場合、i:Interaction.Triggersのようにこれらのトリガーをすべて追加するだけです。次に、このように使用します。

<Window.Resources> 
    <local:EventTriggerCollection x:Shared="False" x:Key="textBoxTriggers"> 
     <i:EventTrigger EventName="GotFocus"> 
      <i:InvokeCommandAction Command="{Binding GotFocusCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TextBox}, Path=Tag}" /> 
     </i:EventTrigger> 
    </local:EventTriggerCollection> 
    <Style TargetType="{x:Type TextBox}"> 
     <Setter Property="local:UIBehaviors.AttachedTriggers" Value="{StaticResource textBoxTriggers}"/> 
    </Style> 
</Window.Resources> 

TextBox.Tagプロパティにバインドする方法に注意してください。データコンテキストは(GotFocusCommandを使用して)ビューモデルになるため、あなたの質問と同様にバインドすることはできません。 トリガー・コレクションがリソース・ディクショナリ内の別の要素としてどのように移動され、x:Shared = "false"に設定されていることにも注意してください。これにより、このプロパティにアクセスするたびに新しいトリガセットが作成されるため、各TextBoxには独自のトリガセットが割り当てられます。

次に任意の

<TextBox Text="Test" Tag="test message" /> 

は、パラメータとして、「テストメッセージ」で、テキストボックスのデータコンテキストにGotFocusCommandを呼び出します。

+0

これは、単一の 'TextBox'にはうまく機能します。私が2番目のものを追加した場合、 'triggers.Add(trigger);行の' 'トリガーのインスタンスを複数のオブジェクトに同時にアタッチできません '' –

+0

修正する。 – Evk

+0

非常に良い。今では、それぞれのTextBoxのために 'Tag'を設定することができます。ありがとう! –

関連する問題

 関連する問題