1

ルーティング イベントが、子要素の前にルート UI 要素にヒットしています。これは期待されていますか?ルーティング イベントを最初に子要素にヒットさせるにはどうすればよいですか?

目的: テキストが「カスタム テキスト ボックス」以外の場所に入力された場合は、「デフォルト テキスト ボックス」にテキストを入力します。

結果: カーソルのフォーカスが「カスタム テキスト ボックス」にある場合でも、custom_PreviewTextInput の前に Window_PreviewTextInput がヒットしています。

どうすればいいですか?


XAML

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight"
        PreviewTextInput="Window_PreviewTextInput"
        >
    <Grid Margin="100,100,100,100">
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="default" Width="100"/>
                <TextBox x:Name="defaultTB" Width="300" Height="50"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="custom" Width="100"/>
                <TextBox x:Name="custom" PreviewTextInput="custom_PreviewTextInput" Width="300" Height="50"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

コードビハインド:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //goal:  if text is typed anywhere except custom textbox, put text in default textbox
        private void Window_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Keyboard.Focus(defaultTB); 
        }

        //goal:  if text is typed in custom TB, put text there, and end the event routing
        private void custom_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            e.Handled = true; 
        }
    }
}
4

1 に答える 1

2

ルーティング イベントは、バブリングまたはトンネリングの可能性があります。あなたはトンネリングイベントの振る舞いをしています。

MSDN から、UIElement.PreviewTextInput イベント:

ルーティング戦略 - トンネリング

対応するバブリング イベントは TextInput です。

ルーティング イベントの概要 - ルーティング戦略:

バブリング: イベント ソースのイベント ハンドラーが呼び出されます。その後、ルーティング イベントは、要素ツリーのルートに到達するまで、連続する親要素にルーティングされます。ほとんどのルーティング イベントは、バブリング ルーティング戦略を使用します。バブリング ルーティング イベントは、通常、個別のコントロールまたは他の UI 要素からの入力または状態の変化を報告するために使用されます。

Direct : ソース要素自体にのみ、応答としてハンドラーを呼び出す機会が与えられます。これは、Windows フォームがイベントに使用する "ルーティング" に似ています。ただし、標準の CLR イベントとは異なり、ダイレクト ルーティング イベントはクラス処理をサポートし (クラス処理については次のセクションで説明します)、EventSetter および EventTrigger で使用できます。

トンネリング: 最初に、要素ツリーのルートにあるイベント ハンドラーが呼び出されます。次に、ルーティング イベントは、ルーティング イベント ソース (ルーティング イベントを発生させた要素) であるノード要素に向かって、ルートに沿って連続する子要素を経由してルートをたどります。トンネリング ルーティング イベントは、多くの場合、コントロールの合成の一部として使用または処理されます。これにより、複合パーツからのイベントを意図的に抑制したり、完全なコントロールに固有のイベントに置き換えたりすることができます。WPF で提供される入力イベントは、多くの場合、トンネリング/バブリングのペアとして実装されます。トンネリング イベントは、ペアに使用される命名規則により、プレビュー イベントと呼ばれることもあります。

于 2011-09-22T14:57:56.240 に答える