views:

1362

answers:

1

I have an AutoCompleteBox inside the CellEditingTemplate for a DataGridTemplateColumn and I am trying to auto-focus on it after a certain number of characters have been entered in a previous column.

I have been able to get the focus to shift and the caret to set appropriately using the BeginInvoke method (described here) but only if the control is a TextBox. when using this method with an AutoCompleteBox the caret does not set nor does the control appear to gain focus.

I attempted to set focus on the AutoCompleteBox manually by obtaining a reference to it inside the setCaretInCurrentCell method and invoking focus but that didn't work either.

I really wannt AutoCompleteBox functionality in this column but the datagrid needs to be optimized for data entry which meeans if the users can't tab or automatically be taken to the next field its a show stopper.

Thanks.

A: 

I might be going with the oddest suggestion on this one, but instead of trying to get inside the grid / control tree and be explicit with things, use the Current Column setting.

Ripping off the data template sample in the help files the XAML and basiccode are as follows:

It's not perfect by a long margin in that:

  • it is just hacking together moving from column 0 to 1 based on the pressing of a space, your requirement on the condition to move focus is more complex.
  • I've not set up two way binding so the edit persists etc. just looked at how to move column.

But when it runs, it does respond to a space and move the cursor into the autocomplete box, highlights the text and if I start typing the autocomplete drop down activates. So in principle, setting the current column seems to provide the behaviour you are after.

A.

Code:

    <UserControl x:Class="SilverlightApplication2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
        xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"
        xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Width="400" Height="300">
        <ScrollViewer VerticalScrollBarVisibility="Auto" BorderThickness="0">
            <StackPanel Margin="10,10,10,10">

                <TextBlock Text="DataGrid with template column and custom alternating row backgrounds:"/>
                <data:DataGrid x:Name="dataGrid5" 
                Height="125" Margin="0,5,0,10"
                AutoGenerateColumns="False"
                RowBackground="Azure"
                AlternatingRowBackground="LightSteelBlue">
                    <data:DataGrid.Columns>
                        <!-- Address Column -->
                        <data:DataGridTemplateColumn Header="Address" Width="300">
                            <data:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Padding="5,0,5,0" Text="{Binding Address}"/>
                                </DataTemplate>
                            </data:DataGridTemplateColumn.CellTemplate>
                            <data:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <TextBox Padding="5,0,5,0" Text="{Binding Address}"/>
                                </DataTemplate>
                            </data:DataGridTemplateColumn.CellEditingTemplate>
                        </data:DataGridTemplateColumn>
                        <!-- Name Column -->
                        <data:DataGridTemplateColumn Header="Name">
                            <data:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Padding="5,0,5,0"
                                        Text="{Binding FirstName}"/>
                                    </StackPanel>
                                </DataTemplate>
                            </data:DataGridTemplateColumn.CellTemplate>
                            <data:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <input:AutoCompleteBox Padding="5,0,5,0"
                                        Text="{Binding FirstName}">
                                            <input:AutoCompleteBox.ItemsSource>
                                                <toolkit:ObjectCollection>
                                                    <system:String>January</system:String>
                                                    <system:String>February</system:String>
                                                    <system:String>March</system:String>
                                                    <system:String>April</system:String>
                                                    <system:String>May</system:String>
                                                    <system:String>June</system:String>
                                                    <system:String>July</system:String>
                                                    <system:String>August</system:String>
                                                    <system:String>September</system:String>
                                                    <system:String>October</system:String>
                                                    <system:String>November</system:String>
                                                    <system:String>December</system:String>
                                                </toolkit:ObjectCollection>
                                            </input:AutoCompleteBox.ItemsSource>
                                        </input:AutoCompleteBox>
                                    </StackPanel>
                                </DataTemplate>
                            </data:DataGridTemplateColumn.CellEditingTemplate>
                        </data:DataGridTemplateColumn>

                    </data:DataGrid.Columns>
                </data:DataGrid>
                <Button Content="test"></Button>
            </StackPanel>
        </ScrollViewer>

    </UserControl>






using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication2
{
    public partial class MainPage : UserControl
     {
        public MainPage()
        {
            InitializeComponent();

            // Set the ItemsSource to autogenerate the columns.

            dataGrid5.ItemsSource = Customer.GetSampleCustomerList();

            dataGrid5.KeyDown += new KeyEventHandler(dataGrid5_KeyDown);

        }

        void dataGrid5_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Space)
            {
                // move to next cell and start editing
                DataGrid grd = (DataGrid)sender;
                if (grd.CurrentColumn.DisplayIndex == 0)
                {
                    // move to column 1 and start the edit
                   grd.CurrentColumn = grd.Columns[1];
                }
            }
        }
    }

    public class Customer
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Address { get; set; }
        public Boolean IsNew { get; set; }

        // A null value for IsSubscribed can indicate 
        // "no preference" or "no response".
        public Boolean? IsSubscribed { get; set; }

        public Customer(String firstName, String lastName, 
            String address, Boolean isNew, Boolean? isSubscribed)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Address = address;
            this.IsNew = isNew; 
            this.IsSubscribed = isSubscribed;
        }

        public static List<Customer> GetSampleCustomerList()
        {
            return new List<Customer>(new Customer[4] {
                new Customer("A.", "Zero", 
                    "12 North", 
                    false, true), 
                new Customer("B.", "One", 
                    "34 West", 
                    false, false),
                new Customer("C.", "Two", 
                    "56 East", 
                    true, null),
                new Customer("D.", "Three", 
                    "78 South", 
                    true, true)
            });
        }
    }

}
Andrew