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

时间:2015-04-24 18:20:28

标签: wpf c#-4.0 mvvm

选中复选框后,我需要完成两项任务。此复选框在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>

但是,在检查复选框时,我收到错误消息,“无法在”DataGrid“类型上找到名为”v:TestDependencyProperty.FlagChecked“的属性

我也尝试过以这种方式绑定       ,但它不起作用 - “无法在”DataGrid“类型上找到名为”FlagChecked“的属性。

不确定这是否是正确的方法。 有人能指出我正确的方向.. ??提前谢谢..

2 个答案:

答案 0 :(得分:0)

在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();
    }

答案 1 :(得分:0)

最后通过添加布尔属性&#34; FocusOnChecked&#34;使其工作。到使用ChangePropertyAction将其集合绑定到datagrid并将属性设置为true或false的类的复选框已选中和取消选中复选框。

<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>

然后为textbox创建了一个附加属性,并用新属性绑定它。

 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>