将 DataGrid 中的文本框聚焦在 CheckBox 的选中事件上

Focusing Textbox in a DataGrid on Checked Event of a CheckBox

选中复选框后,我有两个任务需要完成。此复选框在 DataGrid(绑定到集合)中定义为 DataGridTemplateColumn 的数据模板。 此外,还有一个带有文本框数据模板的 DataGridTemplateColumn。 在选中复选框的事件时,我必须清除同一行文本框的文本,并将焦点设置在该文本框上。 清除文本在使用 EventTrigger 时效果很好。 问题是第二部分,我必须将焦点放在文本框上。 为实现此目标,我想将附加行为与 ChangePropertyAction 一起使用。 为此,我创建了一个依赖属性,希望能得到datagrid的引用,找到需要设置焦点的文本框(稍后会做)。

public class TestDependencyProperty : DependencyObject
{
    public static readonly DependencyProperty
        FlagCheckedProperty =
        DependencyProperty.RegisterAttached(
              "FlagChecked", typeof(bool), typeof(TestDependencyProperty),
        new PropertyMetadata(false, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var datagrid = dependencyObject as DataGrid;
        //get the textbox from the datagrid on which focus
        //has to set and set the focus
    }

    public static bool GetFlagChecked(
        DependencyObject d)
    {
        return (bool)d.GetValue(FlagCheckedProperty);
    }
    public static void SetFlagChecked(
        DependencyObject d, bool value)
    {
        d.SetValue(FlagCheckedProperty, value);
    }
}

这里是 xaml

<DataGrid ItemsSource="{Binding FlagCollection}" AutoGenerateColumns="False" CanUserAddRows="False" Margin="5" 
              VerticalScrollBarVisibility="Auto" v:TestDependencyProperty.FlagChecked="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Non Kittable" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding Flag,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Checked">
                                    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.FlaggedCheckedCommand}" 
                                                           CommandParameter="{Binding}"/>
                                    <isc:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}}}" PropertyName="FlagChecked" Value="True"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </CheckBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Tracking No." Width="2*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding XTrackingNum,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

但是,在选中复选框时我收到错误提示,"Cannot find a property named "v:TestDependencyProperty.FlagChecked" on type "DataGrid"

我也试过这样绑定 ,但它没有用 - "Cannot find a property named "FlagChecked" 类型 "DataGrid"。

不确定这样做是否正确。 有人可以指出我正确的方向..??提前致谢..

在 xaml.cs 中,您设置了文本框的焦点。 选中复选框时在复选框上创建事件。

<CheckBox Name="sampleChkbox" Grid.Row="0" Grid.Column="0" Content="Flag" Checked="sampleChkbox_Checked"/>
<TextBox Name="txtSample" Grid.Row="2" Width="200px" Height="40"/>

     xaml.cs
     private void sampleChkbox_Checked(object sender, RoutedEventArgs e)
    {
        CheckBox chk = sender as CheckBox;
        if((bool)chk.IsChecked)
            txtSample.Focus();
    }

终于通过将布尔值 属性 "FocusOnChecked" 添加到集合绑定到数据网格的 class 并将 属性 设置为 true 或 false使用 ChangePropertyAction 选中和取消选中复选框的事件。

<i:Interaction.Triggers>
                            <i:EventTrigger EventName="Checked">
                                <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DataContext.FlaggedCheckedCommand}" 
                                                       CommandParameter="{Binding}"/>
                                <isc:ChangePropertyAction TargetObject="{Binding}" PropertyName="FocusOnChecked" Value="True"/>
                            </i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
                                    <isc:ChangePropertyAction TargetObject="{Binding}" PropertyName="FocusOnChecked" Value="False"/>
                                </i:EventTrigger>
                        </i:Interaction.Triggers>

然后为文本框创建一个附加的 属性 并将其与新的 属性 绑定。

 public class FocusBehavior : DependencyObject
{
    public static readonly DependencyProperty
        FocusProperty =
            DependencyProperty.RegisterAttached(
                "Focus",
                typeof(bool),
                typeof(FocusBehavior),
                new FrameworkPropertyMetadata(false, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var txtBox = dependencyObject as TextBox;
        if (txtBox == null)
            return;
        if (dependencyPropertyChangedEventArgs.NewValue is bool == false)
            return;
        if ((bool )dependencyPropertyChangedEventArgs.NewValue)
            txtBox.Focus();
    }

    public static bool GetFocus(
        DependencyObject d)
    {
        return (bool)d.GetValue(FocusProperty);
    }
    public static void SetFocus(
        DependencyObject d, bool value)
    {
        d.SetValue(FocusProperty, value);
    }
}

下面是文本框的 xaml。

 <DataTemplate>
    <TextBox vm:FocusBehavior.Focus="{Binding Path= FocusOnChecked}" Text="{Binding TrackingNum,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >    
    </TextBox>
 </DataTemplate>