39

UserControl含む がありTextBoxます。メイン ウィンドウがロードされたら、このテキスト ボックスにフォーカスを設定したいのでFocusable="True" GotFocus="UC_GotFocus"UserControls 定義とFocusManager.FocusedElement="{Binding ElementName=login}"メイン ウィンドウ定義に追加しました。メソッドでは、集中したいコントロールUC_GotFocusを呼び出すだけ.Focus()ですが、これは機能しません。

私がする必要があるのは、アプリケーションの開始時TextBoxUserControl受信フォーカスを設定することだけです。

どんな助けでも感謝します、ありがとう。

4

18 に答える 18

28

最近、メイン ウィンドウが最初に読み込まれたときにストーリーボードを介して表示されるログイン スプラッシュ スクリーンの問題を修正しました。

修正には2つの鍵があったと思います。1 つは、包含要素をフォーカス スコープにすることでした。もう 1 つは、ロード中のウィンドウによってトリガーされたストーリーボードの Storyboard Completed イベントを処理することでした。

このストーリーボードにより、ユーザー名とパスワードのキャンバスが表示され、その後フェードして 100% 不透明になります。重要なのは、ストーリーボードが実行されるまでユーザー名コントロールが表示されなかったため、そのコントロールが表示されるまでキーボードフォーカスを取得できなかったことです。しばらく私を失望させたのは、それが「フォーカス」を持っていたことでした (つまり、フォーカスは true でしたが、これは論理フォーカスのみであることが判明しました)。Kent Boogaart を読むまで、WPF に論理フォーカスとキーボード フォーカスの両方の概念があることを知りませんでした。答えて、Microsoft の WPFリンク テキストを見て

それをしたら、特定の問題の解決策は簡単でした:

1) 包含要素をフォーカス スコープにする

<Canvas FocusManager.IsFocusScope="True" Visibility="Collapsed">
    <TextBox x:Name="m_uxUsername" AcceptsTab="False" AcceptsReturn="False">
    </TextBox>
</Canvas>

2) 完了したイベント ハンドラーをストーリーボードにアタッチする

    <Storyboard x:Key="Splash Screen" Completed="UserNamePassword_Storyboard_Completed">
...
</Storyboard>

3) ユーザー名の TextBox を設定して、ストーリーボードの完了イベント ハンドラーでキーボード フォーカスを設定します。

void UserNamePassword_Storyboard_Completed(object sender, EventArgs e)
{
 m_uxUsername.Focus();
}

item.Focus() を呼び出すと、Keyboard.Focus(this) が呼び出されるため、これを明示的に呼び出す必要はありません。Keyboard.Focus(item) と item.Focus の違いについては、この質問を参照してください。

于 2009-05-07T22:47:59.760 に答える
17

その愚かですが、それは動作します:

しばらく待ってから戻ってきて、必要なフォーカスを設定するスレッドをポップします。要素ホストのコンテキスト内でも機能します。

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

 System.Threading.ThreadPool.QueueUserWorkItem(
                   (a) =>
                        {
                            System.Threading.Thread.Sleep(100);
                            someUiElementThatWantsFocus.Dispatcher.Invoke(
                            new Action(() =>
                            {
                                someUiElementThatWantsFocus.Focus();

                            }));
                        }
                   );

}
于 2009-12-02T22:12:43.723 に答える
7

「アプリケーションの起動時に最初のフォーカスを設定する場合、フォーカスを受け取る要素を PresentationSource に接続し、要素の Focusable と IsVisible を true に設定する必要があります。最初のフォーカスを設定する推奨される場所は、Loaded イベント ハンドラーです。"

(MSDN)

Window (または Control) のコンストラクターに "Loaded" イベント ハンドラーを追加し、そのイベント ハンドラーでターゲット コントロールの Focus() メソッドを呼び出すだけです。

    public MyWindow() {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MyWindow_Loaded);
    }

    void MyWindow_Loaded(object sender, RoutedEventArgs e) {
        textBox.Focus();
    }
于 2010-08-06T06:18:34.657 に答える
7

つい最近、いくつかの TextBlocks を格納するリスト ボックスがありました。テキスト ブロックをダブルクリックして TextBox に変換し、それに焦点を合わせてすべてのテキストを選択できるようにして、ユーザーが新しい名前の入力を開始できるようにしたいと考えました (Adobe レイヤーに似ています)。

とにかく、私はイベントでこれを行っていましたが、うまくいきませんでした。ここでの魔法の弾丸は、イベントを処理するように設定することでした。フォーカスを設定していたと思いますが、イベントがパスを下るとすぐに、論理フォーカスが切り替わりました。

話の教訓は、イベントを処理済みとしてマークしていることを確認してください。それがあなたの問題かもしれません。

于 2009-03-23T15:48:07.740 に答える
3

WPF に焦点を当てた優れた一連のブログ記事を見つけました。

それらはすべて読みやすいですが、3 番目の部分では特に、UserControl の UI 要素にフォーカスを設定する方法を扱います。

于 2010-07-07T08:48:06.340 に答える
2

「WPF Initial Focus Nightmare」を経験した後、スタックに関するいくつかの回答に基づいて、次のことが最善の解決策であることが証明されました。

最初に、App.xaml OnStartup() に以下を追加します。

EventManager.RegisterClassHandler(typeof(Window), Window.LoadedEvent,
          new RoutedEventHandler(WindowLoaded));

次に、'WindowLoaded' イベントを App.xaml にも追加します。

void WindowLoaded(object sender, RoutedEventArgs e)
    {
        var window = e.Source as Window;
        System.Threading.Thread.Sleep(100);
        window.Dispatcher.Invoke(
        new Action(() =>
        {
            window.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));

        }));
    }

フレームワークの競合状態が原因で WPF の初期フォーカスがほとんど失敗するため、スレッド化の問題を使用する必要があります。

アプリ全体でグローバルに使用されているため、次のソリューションが最適であることがわかりました。

それが役に立てば幸い...

オラン

于 2011-01-24T17:37:59.980 に答える
1

fuzquat の回答を拡張メソッドに変換しました。Focus() が機能しなかった場所で、Focus() の代わりにこれを使用しています。

using System;
using System.Threading;
using System.Windows;

namespace YourProject.Extensions
{
    public static class UIElementExtension
    {
        public static void WaitAndFocus(this UIElement element, int ms = 100)
        {
            ThreadPool.QueueUserWorkItem(f =>
            {
                Thread.Sleep(ms);

                element.Dispatcher.Invoke(new Action(() =>
                {
                    element.Focus();
                }));
            });
        }
    }
}
于 2015-12-01T11:57:23.967 に答える
1

私にとってのトリックは、FocusManager.FocusedElement属性でした。最初に UserControl に設定しようとしましたが、うまくいきませんでした。

そこで、代わりに UserControl の最初の子に配置してみました:

<UserControl x:Class="WpfApplication3.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid FocusManager.FocusedElement="{Binding ElementName=MyTextBox, Mode=OneWay}">
    <TextBox x:Name="MyTextBox"/>
</Grid>

...そしてうまくいきました!:)

于 2013-12-18T20:02:27.900 に答える
1

MdiParent プロパティを介して MDI 子として設定された Form 内に含まれる ElementHosts 内の WPF UserControls のホストに特に関連するフォーカスの問題に気付きました。

これが他の人が経験している問題と同じかどうかはわかりませんが、以下のリンクに従って詳細を掘り下げてください.

WindowsForms 子 MDI フォームの ElementHost 内でホストされている WPF UserControl 内でフォーカスを設定する際の問題

于 2009-03-31T20:09:57.497 に答える
0

上記の提案の組み合わせを試した後、次のようにして、子UserControlの目的のテキストボックスにフォーカスを確実に割り当てることができました。基本的に、子コントロールにフォーカスを与え、子UserControlにそのTextBoxにフォーカスを与えます。TextBoxのfocusステートメントはそれ自体でtrueを返しましたが、UserControlにもフォーカスが与えられるまで、目的の結果は得られませんでした。また、UserControlはそれ自体のフォーカスを要求できず、Windowによって指定される必要があったことにも注意する必要があります。

簡潔にするために、ウィンドウとUserControlにLoadedイベントを登録することを省略しました。

private void OnWindowLoaded(object sender, RoutedEventArgs e)
{
    ControlXYZ.Focus();
}

UserControl

private void OnControlLoaded(object sender, RoutedEventArgs e)
{
    TextBoxXYZ.Focus();
}
于 2012-07-19T19:03:03.947 に答える
0

ユーザー コントロール - 2 つのテキスト ボックスを含むスタック パネルがあります。テキスト ボックスは、xaml ではなく、コンストラクターで追加されました。最初のテキスト ボックスにフォーカスしようとしても、何も起こりません。Loaded イベントを使用した siggestion は、私の問題を解決します。Loaded イベントなどで control.Focus() を呼び出すだけです。

于 2011-06-29T14:52:31.280 に答える
0

PageLoaded() または読み込まれたコントロールに設定しましたが、WCF 非同期サービスを呼び出して、フォーカスを失っているように見えることを行っています。私が行うすべてのことの最後にそれを設定する必要があります。それで問題ありませんが、コードに変更を加えると、カーソルも設定していることを忘れてしまうことがあります。

于 2013-08-16T18:14:54.600 に答える
0

ユーザー名テキストボックスにフォーカスを設定すると仮定すると、ユーザーは表示されるたびに直接入力できます。

コントロールのコンストラクターで:

this.Loaded += (sender, e) => Keyboard.Focus(txtUsername);
于 2011-12-23T04:58:05.993 に答える
-2

WPF ユーザー コントロールでキーボード フォーカスをキャンバスに設定する際にも同じ問題がありました。私の解決策

  1. XAML で要素をFocusable="True"
  2. element_mousemoveイベントで簡単なチェックを作成します。

    if(!element.IsKeyBoardFocused)
        element.Focus();
    

私の場合、それはうまくいきます。

于 2012-01-30T13:54:06.000 に答える