0

この質問についてグーグルで検索しましたが、情報を収集できず、添付の動作で添付のイベントを処理できるかどうか疑問に思いました。

クラスで宣言されたイベントと、TextBoxコントロールにアタッチしている動作があります。ボタンがクリックされると、イベントが発生します。このイベントのハンドラーを動作に追加し、イベントハンドラーにロジックを記述しましたが、実行されません。それで、私は、アタッチされた動作がアタッチされたイベントを処理することが可能かどうか疑問に思いましたか?

class ResetInputEventClass
{
    public static readonly RoutedEvent ResetInputEvent =  EventManager.RegisterRoutedEvent("ResetInput",
      RoutingStrategy.Bubble,
      typeof(RoutedEventHandler),
      typeof(ResetInputEventClass));

    public static void AddResetInputEventHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.AddHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

    public static void RemoveResetInputEventHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.RemoveHandler(ResetInputEventClass.ResetInputEvent, handler);
    }
}

これが私のイベントクラスであり、これが動作での処理方法です。

public class MyBehavior : Behavior<TextBoxBase>
{
    public MyBehavior()
    {
        // Insert code required on object creation below this point.

    }        

    protected override void OnAttached()
    {
        base.OnAttached();
        // Insert code that you would want run when the Behavior is attached to an object.
        ResetInputEventClass.AddResetInputEventHandler(AssociatedObject, OnResetInputEvent);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        // Insert code that you would want run when the Behavior is removed from an object.
        ResetInputEventClass.RemoveResetInputEventHandler(AssociatedObject, OnResetInputEvent);
    }

    private void OnResetInputEvent(Object o, RoutedEventArgs e)
    {
        //Logic
    }
}

これが私のXAMLコードです:

<Grid x:Name="LayoutRoot">
    <StackPanel>
        <TextBox Margin="5" Text="Bye" TextWrapping="Wrap" Width="150">
            <i:Interaction.Behaviors>
                <local:MyBehavior/>
            </i:Interaction.Behaviors>
        </TextBox>
        <TextBox Margin="5" Text="Bye" TextWrapping="Wrap" Width="150">
            <i:Interaction.Behaviors>
                <local:MyBehavior/>
            </i:Interaction.Behaviors>
        </TextBox>
        <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
    </StackPanel>
</Grid>

ボタンのクリックイベントでイベントを発生させています

private void MyButton_Click(object sender, RoutedEventArgs e)
{
    RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
    RaiseEvent(eventArgs);
}
4

2 に答える 2

5

あなたの問題は簡単です。テキストボックスはイベントに登録されていますが、テキストボックスの親がそれを上げています。したがって、ハンドラーが呼び出されることはありません。イベントを変更して、バブリングではなくトンネリング イベントにすることができます。または、テキスト ボックスのハンドルを取得できます (コード ビハインドで名前と参照を付けます)。そして、イベントを発生させます。

<Grid x:Name="LayoutRoot">
<StackPanel>
<TextBox Margin="5" x:Name="byeTextBox" Text="Bye" TextWrapping="Wrap" Width="150">
                    <i:Interaction.Behaviors>
                        <local:MyBehavior/>
                    </i:Interaction.Behaviors>
                </TextBox>
<Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
</StackPanel>
</Grid>

コード ビハインドは次のようになります。

private void MyButton_Click(object sender, RoutedEventArgs e)
        {
            RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
            byeTextBox.RaiseEvent(eventArgs);
        }

これで問題が解決するはずです。

于 2013-06-14T20:56:30.423 に答える
3

もちろん可能です。XAMLを見せてください。添付されたイベントが添付された動作をトリガーする方法を説明します。

編集済み

コードビハインドですべてを実行できるため、アタッチされた動作とアタッチされたイベントを使用する必要性はわかりません。

コードビハインドですべてを行う方法は次のとおりです。

プロパティが添付されていないXAMLは次のとおりです。

<Grid>
        <StackPanel>
            <TextBox x:Name="txtBox" Margin="5" Text="Bye" TextWrapping="Wrap" Width="150"/>
            <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
        </StackPanel>
</Grid>

これはコードビハインドです。

    public MainWindow()
    {
        InitializeComponent();
    }

    private void MyButton_Click(object sender, RoutedEventArgs e)
    {
        this.txtBox.Text = "hello";
    }

Nameプロパティをオンに設定TextBoxButtonていて、Window.csのコードビハインドからそれらにアクセスでき、ハンドラーを簡単に記述できるためです。

アタッチされたプロパティを使用してすべてを実行する方法は次のとおりです。

これは、プロパティがアタッチされたソリューションの新しいXAMLです。使用しているのはExpressionBlendまたはSilverlightであり、純粋なWPFではないため、カスタムインタラクションを作成する必要がありました。

<Grid x:Name="LayoutRoot">
        <StackPanel i:Interaction.Behaviour="True">
            <TextBox x:Name="txtBox" Margin="5" Text="Bye" TextWrapping="Wrap" Width="150"/>
            <Button Name="MyButton" Content="Save" Width="50" Height="25" Click="MyButton_Click"/>
        </StackPanel>
    </Grid>

Trueデフォルト値がfalseであり、値が古い値と等しくない場合、適切に変更されたイベントが次のようなカスタムロジックで呼び出されるため、動作をオンに設定する必要がありました。

private void MyButton_Click(object sender, RoutedEventArgs e)
    {
        RoutedEventArgs eventArgs = new RoutedEventArgs(ResetInputEventClass.ResetInputEvent,e.OriginalSource);
        RaiseEvent(eventArgs);
    }

 public class Interaction : DependencyObject
{
    // Using a DependencyProperty as the backing store for Behaviour.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BehaviourProperty =
        DependencyProperty.RegisterAttached("Behaviour", typeof(bool), typeof(Interaction), new PropertyMetadata(false, new PropertyChangedCallback(OnBehaviourChanged)));

    private static void OnBehaviourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        StackPanel sp = (StackPanel)d;
        sp.Dispatcher.BeginInvoke(new Action(() =>
        {
            TextBox tb =  VisualTreeHelper.GetChild(sp, 0) as TextBox;


            ResetInputEventClass.AddResetInputHandler(sp, new RoutedEventHandler((o, a) =>
            {
                // Do here whatever you want, call your custom expressions.
                tb.Text = "hello";
            }));

        }), System.Windows.Threading.DispatcherPriority.Background);
    }
}

falseに変更すると、すでに述べたように呼び出されるプロパティ変更イベントの内部true。アプリケーションがバックグラウンドにあるときにコードを実行するようにディスパッチャに指示して、すべてが初期化されるまで待ちます。次に、を見つけて、イベントTextBoxをトリガーしたときに呼び出されるハンドラーを挿入します。ResetInput

これは非常に複雑なソリューションですが、アタッチされたイベントとアタッチされたプロパティで機能します。

このシナリオでは、コードビハインドを使用することを強くお勧めします。

ResetInputEventClassまた、クラス内でミスをしました。AddメソッドとRemoveメソッドのスペルが正しくありません。

これはあなたがそれらを書くべきだった方法です:

public static void AddResetInputHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.AddHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

    public static void RemoveResetInputHandler(DependencyObject d, RoutedEventHandler handler)
    {
        UIElement uie = d as UIElement;
        if (uie == null)
        {
            return;
        }
        uie.RemoveHandler(ResetInputEventClass.ResetInputEvent, handler);
    }

楽しんでください、私はあなたを助けたと思います。

あなたもこれを達成することができますCommands

于 2013-02-28T14:47:20.810 に答える