3

WPF プロジェクトで .net 4.5 を使用しています。TextBox TextChangedEvent を発生させたいと思います。これは私がやったことです:

tb.RaiseEvent(new RoutedEventArgs(TextBox.TextChangedEvent));

以前、Button.ClickEvent で同じ種類の RaiseEvent を実行したことがありますが、これを行うにはどうすればよいですか?

これにより、次のようなエラーが発生します。

Exception:Thrown: 「'System.Windows.RoutedEventArgs' 型のオブジェクトは、'System.Windows.Controls.TextChangedEventArgs' 型に変換できません。」(System.ArgumentException) System.ArgumentException がスローされました: 「'System.Windows.RoutedEventArgs' 型のオブジェクトは、'System.Windows.Controls.TextChangedEventArgs' 型に変換できません。

[編集]

変更された実際のテキスト ボックスのテキストは、次のように添付された動作によって処理されます。プログラムでイベントを発生させたい場所は、別のコントロールの添付された動作にあります。後の動作では、テキスト ボックス オブジェクトがあります。

public class textboxTextChangedBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.TextChanged += OnTextChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.TextChanged -= OnTextChanged;
        base.OnDetaching();
    }

    private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            //Populate ObservableCollection
        }
    }
}

イベントを発生させようとする場所:

public class FindPopupBehavior : Behavior<Popup>
{
    protected override void OnAttached()
    {
        AssociatedObject.Opened += _OpenFindPopup;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Opened -= _OpenFindPopup;
    }

    void _OpenFindPopup(object sender, EventArgs e)
    {
        //Fake a TextBox text changed event
        if (TextBoxObject == null)
            return;

        TextBox tb = TextBoxObject as TextBox;

        if (tb.Text == "")
            return;

        tb.RaiseEvent(new RoutedEventArgs(TextBox.TextChangedEvent));
    }

    public static readonly DependencyProperty TextBoxProperty =
        DependencyProperty.Register("TextBoxObject", typeof(TextBox), typeof(FindPopupBehavior), new UIPropertyMetadata(null));

    public object TextBoxObject
    {
        get { return (object)GetValue(TextBoxProperty); }
        set { SetValue(TextBoxProperty, value); }
    }
}

[編集2]

ObservableCollection を閉じるこのポップアップがクリアされると、テキスト ボックスはポップアップに存在し、テキスト ボックスのテキストは非表示になりますが残ります。ポップアップが再度開かれ、テキスト ボックスにテキストがある場合は、ObservableCollection を再設定する必要があります。これは、textchanged 動作でこのポピュレーションを行います。これが、私がイベントを偽造することを考えていた理由です。

4

5 に答える 5

2

手動で .NET イベントを発生させることは、それが不要であること以外の理由がなくても、お勧めできません。考えてみてください...あなたは本当にイベントを発生させたくありません。イベントの機能を求めていないのに、なぜそれを上げるのですか?

私があなたの状況を正しく理解していれば、あなたが実際にやりたいことは、コードの特定のセクションを実行することです。そのため、コードのそのセクションが現在イベント ハンドラー内にカプセル化されているため、問題が発生します。ただし、そのコードを実行するためにそのイベントを発生させる必要があるという意味ではありません。

代わりに、関連するコードをメソッドに移動するだけで、イベント ハンドラーその他の任意の場所から呼び出すことができ、不必要にイベントを発生させることはありません。

private void OnTextChanged(object sender, TextChangedEventArgs args)
{
    var textBox = (sender as TextBox);
    if (textBox != null)
    {
        PopulateObservableCollection();
    }
}

private void PopulateObservableCollection()
{
    // Populate ObservableCollection
}

特に にアクセスする必要がある場合はTextBox、状況を詳しく説明してください... 方法は常にあります。


更新 >>>

これについて論理的に考えてみてください...このメソッドを呼び出す必要があり、TextBox内の にアクセスする必要があり、が開かPopupれるたびにそれを行う必要があります。Popupそれでは、Popup.Openedイベントを処理しないのはなぜですか?:

private void PopupOpened(object sender, EventArgs e)
{
    // Check TextBox and Populate ObservableCollection
}
于 2014-06-24T08:40:39.080 に答える
1

次のように手動でイベントを発生させることができます

    MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,100, MouseButton.Left);
    args.RoutedEvent = UIElement.PreviewMouseLeftButtonUpEvent;
    tb.RaiseEvent(args);
于 2014-06-24T06:38:52.327 に答える
0

イベントのメソッドを直接呼び出してみませんか? 小さなサンプル アプリケーションを作成しました。

次のことを行います。

  • ボタンとテキストボックスがあります。テキストボックスにはOnTextChangedイベントがあり、ボタンをクリックしたときにそのテキストボックスイベントを実行したいです。

まず、私の場合、テキスト ボックスとボタンを含むグリッドのみを含む WPF アプリケーションです。

<Grid>
    <TextBox Name="txtTextBox"></TextBox>
    <Button Name="btnDemo" Content="Click me"></Button>
</Grid>

レイアウトが賢明であることはわかっていますが、これはゴミですが、デモンストレーションのためだけです。

コード ビハインドでは、いくつかのことを行う必要があります。

ボタンとテキスト ボックスのイベント ハンドラーを追加します。

public MainWindow()
{
    InitializeComponent();

    btnDemo.Click += BtnDemoOnClick;
    txtTextBox.TextChanged += TxtTextBoxOnTextChanged;
}

TxtTextBoxOnTextChanged イベントのコードは次のとおりです。

private void TxtTextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
    MessageBox.Show("The textbox event has been fired.");
}

ご覧のとおり、これはメッセージ ボックスを表示するだけです。

そして、あなたのボタンのイベント:

private void BtnDemoOnClick(object sender, RoutedEventArgs routedEventArgs)
{
    TxtTextBoxOnTextChanged(this, new TextChangedEventArgs(routedEventArgs.RoutedEvent, UndoAction.None));
}

お役に立てば幸いです。

于 2014-06-24T06:42:52.920 に答える
0

オブジェクトのイベントをリコールすると、再びキャッチされるため、これはスタックオーバーフローで終了する可能性があります。textboxTextChangedBehavior

ループを作成する代わりに、簡単に変更できます

private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {}
    }

private void OnTextChanged(object sender, TextChangedEventArgs args)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {}

        // now your textboxTextChangedBehavior does't block your event 
        args.Handled = false;
    }

[編集]

うーん、おそらく問題は、目標を達成する方法です。

しかし、私があなたのポップアップを正しく理解しているならOpened、あなたは を上げようとしますよTextChangedね?

そのため、テキストを設定して_OpenFindPopup(# を追加するなど)、それによって値が上がりTextChanged、# を削除して、ObservableCollection

于 2014-06-24T07:39:49.287 に答える
0

1つの方法は、このようにすることができます..

   EventName.Raise(this, new EventArgs());
于 2014-06-24T06:37:48.117 に答える