Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set focus to 1st textbox in items control

Let's say I have an items control that is bound to a list of items on the VM. Inside the datatemplate is a textbox. How would I set focus to the first textbox in either XAML or the VM?

Thanks in advance for any help!

<ItemsControl ItemsSource="{Binding UsageItems}" Grid.Row="1" Focusable="False">
<ItemsControl.ItemTemplate>
    <DataTemplate>
            <Grid Margin="0,0,0,3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <TextBlock Text="{Binding Month}" Style="{StaticResource Local_MonthLabel}" />
            <core:NumericTextBox Value="{Binding Actual, Mode=OneWay}" Style="{StaticResource Local_ActualUsageEntry}" Grid.Column="2"/>

            <core:ValidationControl Instance="{Binding Model}" Grid.Column="4" PropertyName="{Binding MonthNumber, StringFormat=AdjustedUsage{0}}">
                <core:NumericTextBox Value="{Binding Adjusted}"  DefaultValueIfNull="0" Style="{StaticResource Local_AdjustUsageEntry}" x:Name="AdjustmentEntry" inventoryLocationSetup:InitialFocusBehavior.Focus="True" />
            </core:ValidationControl>

            <telerik:RadComboBox ItemsSource="{Binding Converter={StaticResource Converter_EnumToEnumMemberViewModel}, Mode=OneTime, Source={x:Type Enums:UsageAdjustmentTypes}}" SelectedValue="{Binding Code, Mode=TwoWay}" Grid.Column="6" Style="{StaticResource Local_CodeSelector}"/>

        </Grid>
    </DataTemplate>
</ItemsControl.ItemTemplate>

like image 262
user2041189 Avatar asked May 01 '13 21:05

user2041189


1 Answers

I use an attached behaviour:

public static class InitialFocusBehavior
{
    public static bool GetFocus(DependencyObject element)
    {
        return (bool)element.GetValue(FocusProperty);
    }

    public static void SetFocus(DependencyObject element, bool value)
    {
        element.SetValue(FocusProperty, value);
    }

    public static readonly DependencyProperty FocusProperty =
        DependencyProperty.RegisterAttached(
        "Focus",
        typeof(bool),
        typeof(InitialFocusBehavior),
        new UIPropertyMetadata(false, OnElementFocused));

    static void OnElementFocused(
        DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = depObj as FrameworkElement;
        if (element == null)
            return;
        element.Focus();
    }
}

Then in the XAML bind it to True for the element you want focused:

<TextBox Width="200" Height="20" local:InitialFocusBehavior.Focus="True" />

=== UPDATE ===

Sorry, the code above just shows how to use a behaviour to give focus to a control on the page, if you want to do it to an element in the first item in an ItemControl then you'll have to instead apply the behavior to the ItemsControl itself and then in your update handler find the child by doing something like this instead:

static void OnElementFocused(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
    ItemsControl itemsControl = depObj as ItemsControl;
    if (itemsControl == null)
        return;
    itemsControl.Loaded += (object sender, RoutedEventArgs args) =>
    {
        // get the content presented for the first listbox element
        var contentPresenter = (ContentPresenter)itemsControl.ItemContainerGenerator.ContainerFromIndex(0);

        // get the textbox and give it focus
        var textbox = contentPresenter.ContentTemplate.FindName("myTextBox", contentPresenter) as TextBox;
        textbox.Focus();
    };
}

You'll notice that I'm setting the focus inside the OnLoaded handler because I'm assuming that the items won't have been attached yet when the control is first created.

Also you've probably already figured it out by "local" is just the namespace that the InitialFocusBehavior class is defined in, you'll need to add something like this at the top of the xaml:

xmlns:local="clr-namespace:YourProjectNamespace"
like image 150
Mark Feldman Avatar answered Nov 15 '22 11:11

Mark Feldman