Laden...

[erledigt] Focus beim Laden auf eine TextBox setzen [==> FocusManager.FocusedElement binden]

Letzter Beitrag vor 11 Jahren 11 Posts 5.235 Views
[erledigt] Focus beim Laden auf eine TextBox setzen [==> FocusManager.FocusedElement binden]

Hallo!

Ich habe ein Window, wo man was in eine Textbox eingeben soll.

Nun hätte ich gerne, dass diese Textbox gleich beim Öffnen des Wins den Focus hat.
Derzeit muß man immer noch die Tab-Taste drücken.

Habe Textbox.TabIndex=0, Window.TabIndex=99, Window.Focusable=False, und mehr fällt mir nicht mehr ein, was ich versuchen könnte 🙁

Der frühe Apfel fängt den Wurm.

Und im FormLoad/FormShown-Event einfach textBox.Select() machen hilft nicht?

Ich würde das selbe wie dN!3L versuchen wenn das nichtklappt dem window einfach ein onLoad event geben in dem du sagst TextBoxName.Focus()

Hallo ErfinderDesRades,

gib das FocusesElement als Eigenschaft des Window an:


FocusManager.FocusedElement="{Binding ElementName=myTextBox}"

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Jo, wenn man weiß, wies geht, und wohin, ist garnimmer schwer! 😉

<Window x:Class="ValidforSelect"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
        FocusManager.FocusedElement="{Binding ElementName=txtTypeCompletion}"
        >

thx!

Der frühe Apfel fängt den Wurm.

HI,

ich würde gerne den Thread kurz reaktivieren ohne den Zustand "[erledigt]" gleich zu entfernen...

Und zwar möchte ich per Binding aus dem ViewModel heraus angeben, welches Control nach dem Laden des Windows den Focus erhalten soll. Klar kann man darüber streiten, ob das VM den Namen eines Controls aus der View kennen sollte oder nicht, aber ich sehe gerade keine andere Lösung:

Ich nutze also

<Window ... FocusManager.FocusedElement="{Binding DefaultControl}/>"

wobei "DefaultControl" eine Eigenschaft meines als DataContext dem Window übergebenen VM ist. Leider funktioniert das nicht wie es soll. Wenn ich statt "Binding..." direkt den Namen des Controls angeben funktioniert es.

Was könnte falsch sein? Welchen Typs muß DefaultControl sein? Zur Zeit ist im VM ein String der den Namen des Controls angibt.

Wie könne ich sonst das fokussierte Control angeben? Wenn ich's im COde-Behind mache, müsste ich doch für jedes Window eine eigene Window-Klasse erstellen die dann nur den Kode zum setzen des Focus hätte da der restliche Aufbau der Fenster bei mir aus Styles/Templates kommen.

Vielen Dank für Eure Antworten!

Gruß,
Pascal

It's not a bug, it always worked that way!
Codegrunts
XING

Hallo,

da FocusManager.FocusedElement als Typ 'System.Windows.IInputElement' hat, muß also auch dein VM-Property diesen Typ haben (also nicht den Namen als String, sondern eine Referenz auf das Control).
Wenn du in deinem ViewModel doch nur per String die Controls kennst, so kannst du mit der FindName-Methode dir die Control-Referenz besorgen (du benötigst dafür natürlich eine Referenz auf das Window d.h. die View - daher wäre es besser hier dann eine Schnittstelle zu definieren und diese dann an das ViewModel zu übergeben).

Edit: schau dir aber auch mal MVVM, WPF focus uilelement from viewmodel an...

Alles klar, vielen Dank für die Antwort!

Da ich meine Controls alle per Style/Template auf dem Window bringe noch folgende Frage:

Funktioniert "FindName" dann auch um Controls zu finden die aus den Templates stammen?

It's not a bug, it always worked that way!
Codegrunts
XING

... dann schau mal in
>
...

Danke für die Links. Genau das hatte ich auch versucht... Ich habe nun versucht es zu machen wie in dem obigen Link:

(Grid)myButton1.Template.FindName("grid", myButton1);

Bei mir also:

(IInputElement)wStandardWindow.Template.FindName(aControlName, wStandardWindow);

Aber es kommt immer null bei raus... 😦

So sieht das Window.xaml aus:


<Window x:Class="RvWIN.Framework.Views.StandardWindow"
...
        Height="300" Width="300" WindowStartupLocation="CenterScreen"
        Name="wStandardWindow"
        Title="{Binding WindowTitle}" 
        FocusManager.FocusedElement="{Binding DefaultControl}"
>
    <Grid>
    </Grid>
</Window>

Der Style der das Template auf das Fenster wirklen lässt:


    <Style x:Key="ListWindowStyleDX" TargetType="Window">
        <Setter Property="Template" Value="{StaticResource ListWindowTemplate}"/>
    </Style>

und das Template:


<ControlTemplate x:Key="ListWindowTemplate" TargetType="Window">
        <ControlTemplate.Resources>
...
        </ControlTemplate.Resources>
        <dxb:BarManager >
            <dxb:BarManager.Items>
...
            </dxb:BarManager.Items>
            <dxb:BarManager.Bars>
                <dxb:Bar Name="barMenu" Caption="" UseWholeRow="True" GlyphSize="Large" RotateWhenVertical="False" AllowHide="False" AllowQuickCustomization="False" AllowCustomizationMenu="False" BarItemHorzIndent="10"
                             ItemLinksSource="{Binding BarCommands}" ItemTemplateSelector="{StaticResource BarItemTemplateSelector}" >
                    <dxb:Bar.DockInfo>
                        <dxb:BarDockInfo ContainerType="Right"/>
                    </dxb:Bar.DockInfo>
                </dxb:Bar>
            </dxb:BarManager.Bars>
            <dxg:GridControl Name="grdRecords" ShowLoadingPanel="False" AllowMRUFilterList="True" IsFilterEnabled="True" Margin="0" ShowBorder="False" 
                                 ItemsSource="{Binding DataSource}" ColumnsSource="{Binding GridColumns}" >
...
            </dxg:GridControl>
        </dxb:BarManager>
    </ControlTemplate>

Das Grid hat den Namen "grdRecords" doch

(IInputElement)wStandardWindow.Template.FindName("grdRecords", wStandardWindow);

bringt immer null...

Muß ich irgendwie rekursiv durch die Controls des Templates durch? Denn das Grid ist ja nicht das oberste der Controls im Template...

Gruß,
Pascal

It's not a bug, it always worked that way!
Codegrunts
XING

Ok, ich weiß jetzt warum das nicht geht.

Die Methode die letztlich FindName aufruft wird durch ein Binding getriggert. Es ist der getter der Property "DefaultControl" meines VMs welche ja widerum mit "FocusManager.FocusedElement" gebunden ist.

Offensichtlich wird dieses Binding getriggert BEVOR das Template geladen wird denn wenn ich die gleichen Zeilen in "OnApplyTemplate" hinein kopiere funktioniert FindName einwandfrei. Auch beim Debuggen geht er erst in den getter und dann später in OnApplyTemplate...

Kann das wirklich sein, dass "FocusManager.FocusedElement="{Binding DefaultControl}" zuschlägt bevor das Template richtig geladen ist??

It's not a bug, it always worked that way!
Codegrunts
XING