UserControl
を含むTextBox
があります。メインウィンドウが読み込まれたら、このテキストボックスにフォーカスを設定するため、UserControl
s定義に_Focusable="True" GotFocus="UC_GotFocus"
_を追加し、メインウィンドウ定義に_FocusManager.FocusedElement="{Binding ElementName=login}"
_を追加しました。 _UC_GotFocus
_メソッドでは、フォーカスしたいコントロールで.Focus()
を呼び出すだけですが、これは機能しません。
私がする必要があるのは、TextBox
にUserControl
があり、アプリケーションの起動時にフォーカスを受け取ることです。
どんな助けでも感謝します、ありがとう。
私は最近、メインウィンドウが最初に読み込まれたときにストーリーボードを介して表示されるログインスプラッシュスクリーンのこの問題を修正しました。
修正には2つの鍵があったと思います。 1つは、包含要素をフォーカススコープにすることでした。もう1つは、読み込まれているウィンドウによってトリガーされたストーリーボードのStoryboard Completedイベントを処理することでした。
このストーリーボードは、ユーザー名とパスワードのキャンバスを表示し、100%不透明になるまでフェードします。重要なのは、ストーリーボードが実行されるまでユーザー名コントロールが表示されなかったため、そのコントロールが表示されるまでkeyboardフォーカスを取得できなかったことです。しばらく私を驚かせたのは、「フォーカス」があるということです(つまり、フォーカスは真でしたが、これは論理的なフォーカスにすぎませんでした)、KPF Boogaartの答えて、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の違い に関するこの質問を参照してください
その愚かですが、それは動作します:
しばらく待ってから戻ってきて、必要なフォーカスを設定するスレッドをポップします。要素Hostのコンテキスト内でも機能します。
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();
}));
}
);
}
つい最近、いくつかのTextBlockを格納するリストボックスがありました。テキストブロックをダブルクリックしてTextBoxに変えてから、それに焦点を合わせてすべてのテキストを選択できるようにしたかったので、ユーザーは新しい名前の入力を開始できます(Adobe Layersと同様)
とにかく、私はイベントでこれをしていましたが、うまくいきませんでした。ここでの私にとっての特効薬は、イベントを処理するように設定することでした。私はそれを考えますwasフォーカスを設定しますが、イベントがパスを下るとすぐに、論理フォーカスを切り替えていました。
ストーリーの教訓は、イベントを処理済みとしてマークしていることを確認することです。これが問題になる可能性があります。
「アプリケーションの起動時に初期フォーカスを設定する場合、フォーカスを受け取る要素を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();
}
fuzquatのソリューションを試してみて最も一般的なものであることがわかったので、別のバージョンを共有すると思ったのです。ここにあります:
casted.Dispatcher.BeginInvoke(new Action<UIElement>(x =>
{
x.Focus();
}), DispatcherPriority.ApplicationIdle, casted);
thread.Sleep、ThreadPoolはありません。十分にきれいに願っています。私は他の人々のソリューションにコメントできるように本当にいくつかの担当者を使用できます。
更新:
人々はきれいなコードを好むようだから:
public static class WpfExtensions
{
public static void BeginInvoke<T>(this T element, Action<T> action, DispatcherPriority priority = DispatcherPriority.ApplicationIdle) where T : UIElement
{
element.Dispatcher.BeginInvoke(priority, action);
}
}
これで次のように呼び出すことができます:
child.BeginInvoke(d => d.Focus());
WPFは、2種類のフォーカスをサポートしています。
FocusedElement
プロパティは、フォーカススコープ内の論理フォーカスを取得または設定します。 TextBox
doesに論理的なフォーカスがあると思われますが、そのフォーカススコープはアクティブフォーカススコープではありません。エルゴ、それしないキーボードフォーカスを持っています。
質問は、ビジュアルツリーに複数のフォーカススコープがありますか?
入力中にこのソリューションで実行するサンプルアプリがあります。これがうまくいかない場合は、問題の原因となるアプリまたは環境に固有のものが必要です。あなたの元の質問では、バインディングが問題を引き起こしていると思います。これがお役に立てば幸いです。
WPFフォーカスに関する一連の優れたブログ記事を見つけました。
これらはすべて読むのに適していますが、第3部では特にUserControlのUI要素にフォーカスを設定することを扱います。
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();
}));
});
}
}
}
MdiParentプロパティを介してMDI子として設定されているフォーム内に含まれるElementHosts内のWPF UserControlsのホストに特に関連するフォーカスの問題に気付きました。
これが他の人が経験しているのと同じ問題であるかどうかはわかりませんが、以下のリンクに従って詳細を掘り下げてください。
WindowsForms子のElementHost内でホストされるWPF UserControl内にフォーカスを設定する際の問題MDI form
私にとってのトリックは、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>
...そしてそれはうまくいきました! :)
「WPF Initial Focus Nightmare」を取得し、スタックに関するいくつかの回答に基づいて、次のことが最良のソリューションであることが証明されました。
まず、次のApp.xaml OnStartup()を追加します。
EventManager.RegisterClassHandler(typeof(Window), Window.LoadedEvent,
new RoutedEventHandler(WindowLoaded));
次に、App.xamlにも「WindowLoaded」イベントを追加します。
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の初期フォーカスがほとんど失敗するため、スレッドの問題を使用する必要があります。
アプリ全体でグローバルに使用されているため、次のソリューションが最適であることがわかりました。
それが役に立てば幸い...
オラン
PageLoaded()またはロードされたコントロールに設定しますが、その後、WCF非同期サービスを呼び出して、フォーカスを失いそうなことをしています。私はすべてのことの最後に設定する必要があります。これで問題ありませんが、コードに変更を加えると、カーソルを設定していることを忘れてしまうことがあります。
UserControlに別のタブスコープを設定するソリューションは好きではありません。その場合、キーボードでナビゲートするときに2つの異なるキャレットがあります。ウィンドウ上ともう1つ-ユーザーコントロール内です。私の解決策は、ユーザーコントロールから内側の子コントロールにフォーカスをリダイレクトすることです。ユーザーコントロールをフォーカス可能に設定します(既定ではfalseであるため)。
<UserControl ..... Focusable="True">
コードビハインドでフォーカスイベントハンドラーをオーバーライドします。
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
MyTextBox.Focus();
}
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
Keyboard.Focus(MyTextBox);
}
ユーザー名テキストボックスにフォーカスを設定すると仮定すると、ユーザーは表示されるたびに直接入力できます。
コントロールのコンストラクターで:
this.Loaded += (sender, e) => Keyboard.Focus(txtUsername);
ユーザーコントロールがあります-2つのテキストボックスがあるスタックパネル。テキストボックスは、xamlではなく、コンストラクターに追加されました。最初のテキストボックスにフォーカスしようとすると、何も起こりませんでした。 Loadedイベントでのsiggestionは私の問題を修正します。 Loadedイベントおよびその他すべてでcontrol.Focus()を呼び出しました。
上記の提案の組み合わせを試した後、次の方法で子UserControlの目的のテキストボックスに確実にフォーカスを割り当てることができました。基本的に、子コントロールにフォーカスを与え、子UserControlにそのTextBoxにフォーカスを与えます。 TextBoxのフォーカスステートメントはそれ自体でtrueを返しましたが、UserControlにもフォーカスが与えられるまで、目的の結果は得られませんでした。また、UserControlはそれ自体にフォーカスを要求することができず、Windowによって提供されなければならなかったことにも注意する必要があります。
簡潔にするため、WindowおよびUserControlのLoadedイベントの登録は省略しました。
窓
private void OnWindowLoaded(object sender, RoutedEventArgs e)
{
ControlXYZ.Focus();
}
UserControl
private void OnControlLoaded(object sender, RoutedEventArgs e)
{
TextBoxXYZ.Focus();
}