C# WPF选项卡进入数据绑定项控件

C# WPF选项卡进入数据绑定项控件,c#,wpf,data-binding,itemscontrol,C#,Wpf,Data Binding,Itemscontrol,在我的WPF应用程序中,我有一个数据绑定的TextBox和一个数据绑定的ItemsControl。项控件的内容由文本框的内容决定。我希望能够在文本框中键入一个值,按tab键并在项目控件中输入第一项(根据文本框中的值创建)。我遇到的问题是,在WPF在ItemsControl中创建模板化项之前,会计算tab操作。以下代码演示了此问题: <Window x:Class="BindingExample.Window1" x:Name="SelfControl" xmlns="http://

在我的WPF应用程序中,我有一个数据绑定的
TextBox
和一个数据绑定的
ItemsControl
项控件的内容由
文本框的内容决定。我希望能够在
文本框中键入一个值,按tab键并在
项目控件中输入第一项(根据
文本框中的值创建)。我遇到的问题是,在WPF在
ItemsControl
中创建模板化项之前,会计算tab操作。以下代码演示了此问题:

<Window x:Class="BindingExample.Window1" x:Name="SelfControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc="clr-namespace:BindingExample" Title="Window1" Height="300" Width="400">
    <Window.Resources>
        <DataTemplate DataType="{x:Type loc:ChildClass}">
            <TextBox Text="{Binding Value}" />
        </DataTemplate>
    </Window.Resources>
    <StackPanel DataContext="{Binding ElementName=SelfControl}" Focusable="False">
        <Label Content="Options: A, B, C" />
        <TextBox Text="{Binding Object.Value}" />
        <ItemsControl Margin="16,0,0,0" ItemsSource="{Binding Object.Children}" Focusable="False">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <TextBox Text="Box2" />
    </StackPanel>
</Window>


使用System.Collections.Generic;
使用系统组件模型;
使用System.Windows;
名称空间绑定示例
{
公共部分类窗口1
{
public static readonly dependencProperty ObjectProperty=dependencProperty.Register(“Object”、typeof(ParentClass)、typeof(Window1));
公共父类对象
{
获取{返回GetValue(ObjectProperty)作为父类;}
set{SetValue(ObjectProperty,value);}
}
公共窗口1()
{
初始化组件();
对象=新的父类();
}
}
公共类父类:INotifyPropertyChanged
{
私有字符串值;
公共字符串值
{
获取{返回值;}
设置{this.value=value;if(PropertyChanged!=null)PropertyChanged(this,newpropertychangedventargs(“Children”);}
}
可数儿童的公共教育
{
得到
{
开关(Value.ToUpper())
{
案例“A”:返回新的子类[]{“A-1”、“A-2”、“A-2”};
案例“B”:返回新的子类[]{“B-1”、“B-2”、“B-3”};
案例“C”:返回新的子类[]{“C-1”、“C-2”、“C-2”};
默认值:返回新的子类[]{“未知”};
}
}
}
公共事件属性更改事件处理程序属性更改;
}
公营儿童班
{
公共字符串值{get;set;}
公共静态隐式运算符ChildClass(字符串值){返回新的ChildClass{value=value};}
}
}
在这段代码中,我想在第一个
文本框
中键入“A”,按tab键,然后将焦点转移到带有文本“A-1”的子
文本框
。取而代之的是,焦点跳转到带有文本“Box2”的文本框。我怎样才能达到我在这里所期望的行为


注意:正如Julien Poulin指出的,可以通过将
文本框上的
更新资源记录器
切换到
属性更改
来实现这一点。然而,这只有在“按您的类型”绑定是可接受的情况下才有效。在我的例子中,我还希望通过一次按键来设置值和制表符。有什么方法可以强制ItemsControl按需创建其模板项目吗?

尝试将
文本框的
UpdateMode
设置为
PropertyChanged
,以便在键入新值时而不是在
文本框失去焦点时设置基础值:

<TextBox Text="{Binding Path=Object.Value, UpdateMode=PropertyChanged}" />

尝试将
文本框的
UpdateMode
设置为
PropertyChanged
,以便在键入新值时而不是在
文本框失去焦点时设置基础值:

<TextBox Text="{Binding Path=Object.Value, UpdateMode=PropertyChanged}" />

这里有一个替代解决方案。这有点像黑客,但似乎有效。由于在主线程上暂停执行之前,
ItemsControl
中的模板化对象不会创建,因此此代码捕获选项卡,更新绑定,并设置计时器,以便在有机会创建项时移动焦点

...
<TextBox Text="{Binding Object.Value}" KeyDown="TextBox_KeyDown" />
...

我在这段代码中看到的唯一问题是,
ItemsControl
可能需要10毫秒以上的时间来填充,在这种情况下,选项卡将跳过这些项。是否有任何方法可以检测是否创建了
ItemsControl
项?

这里是另一种解决方案。这有点像黑客,但似乎有效。由于在主线程上暂停执行之前,
ItemsControl
中的模板化对象不会创建,因此此代码捕获选项卡,更新绑定,并设置计时器,以便在有机会创建项时移动焦点

...
<TextBox Text="{Binding Object.Value}" KeyDown="TextBox_KeyDown" />
...

我在这段代码中看到的唯一问题是,
ItemsControl
可能需要10毫秒以上的时间来填充,在这种情况下,选项卡将跳过这些项。是否有任何方法可以检测是否创建了
ItemsControl
项?

此方法有效。但是,理想情况下,我希望在控件失去焦点时进行绑定,而不是在用户键入时进行绑定。我认为无法在ItemsControl内的文本框上自动设置焦点,因为当第一个文本框失去焦点时,它们尚未创建。你可以写一些代码把焦点放回它所属的地方,但是看起来会很混乱。这很有效。但是,理想情况下,我希望在控件失去焦点时进行绑定,而不是在用户键入时进行绑定。我认为无法在ItemsControl内的文本框上自动设置焦点,因为当第一个文本框失去焦点时,它们尚未创建。您可以编写一些代码来将焦点放回它所属的位置,但看起来会非常混乱。