繁体   English   中英

在 KeyBinding 中将控件绑定为 CommandParameter

[英]Bind Control as CommandParameter in KeyBinding

我正在尝试将 Control 作为 ComandParamter 发送,以便我可以专注于它。 这些控件位于 GridViewColumn HeaderTemplate 中,据我所知,tab 键不能跨越标题。 我的研究使我使用x:reference因为ElementName由于命名范围而失败。 该命令已正确绑定,当我未绑定 CommandParameter 时它确实会运行。

使用下面 xaml 中显示的绑定,我收到此错误:

尝试引用尚未定义的命名对象“resourcetypeSrch”。 Key 以外的指令不支持前向引用或对包含前向引用的对象的引用。

如何将带有x:Name resourcetypeSrch的 ComboBox 绑定到 TextBox KeyBinding CommandParameter?

<GridViewColumn DisplayMemberBinding="{Binding Name }">
    <GridViewColumn.HeaderTemplate>
        <DataTemplate>
            <DockPanel>
                <TextBlock Text="{StaticResource Name}" />
                <TextBox Text="{Binding DataContext.Foo, RelativeSource={RelativeSource AncestorType=Page}}"                                             
                         Style="{StaticResource SearchBox }" Width="200">
                    <TextBox.InputBindings>
                        <KeyBinding Key="Tab" 
                                    Command="{Binding DataContext.SearchNavigationCmd, RelativeSource={RelativeSource AncestorType=Page}}"
                                    CommandParameter="{Binding {x:Reference resourcetypeSrch}}"/>
                    </TextBox.InputBindings>

                </TextBox>
            </DockPanel>
        </DataTemplate>
    </GridViewColumn.HeaderTemplate>
</GridViewColumn>

<GridViewColumn Width="350" DisplayMemberBinding="{Binding ResourceTypeLookup.TypeName }">
    <GridViewColumn.HeaderTemplate>
        <DataTemplate>
            <DockPanel>
                <TextBlock Text="{StaticResource ResourceType}" />
                <ComboBox x:Name="resourcetypeSrch" Width="300" HorizontalAlignment="Left" IsSynchronizedWithCurrentItem="True"
                      ItemsSource="{Binding DataContext.SrchResourceTypeLookups, RelativeSource={RelativeSource AncestorType=Page}, Mode=OneTime}" 
                      DisplayMemberPath="TypeName"
                      SelectedValuePath="Bar"
                      SelectedValue="{Binding DataContext.Fizz, RelativeSource={RelativeSource AncestorType=Page}}" >
                </ComboBox>
            </DockPanel>
        </DataTemplate>
    </GridViewColumn.HeaderTemplate>
</GridViewColumn>

您需要在 KeyBinding 中为 CommandParameter 使用 RelativeSource 绑定:

<KeyBinding Key="Tab" 
        Command="{Binding DataContext.SearchNavigationCmd, RelativeSource={RelativeSource AncestorType=Page}}"
        CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"/>

此代码将查找控件树,直到找到 ComboBox 类型的控件。 在您的特定情况下,它将找到的第一个 ComboBox 将是您需要的。

我相信您希望能够在网格标题中的控件中进行选项卡导航。 您可以做的是在您的数据源中为每列创建一个属性(即 Column1IsFocused、Column2IsFocused)。

然后你可以创建一个扩展来从视图模型集中你的控件(例如这里是一个)。 您将扩展的 IsFocused 属性绑定到 dataSource 中的每个属性,然后在命令处理程序中将一个或另一个属性设置为 true。 我相信这可能会奏效。

我只是想了另一种可能性。 您可以在命令处理程序方法中遍历可视化树并按名称找到您的控件。 这是一个很好的方法实现,它遍历对象的 VisualTree 并查找具有指定方法的控件:

public static T FindChild<T>(DependencyObject parent, string childName)
   where T : DependencyObject
{    
  // Confirm parent and childName are valid. 
  if (parent == null) return null;

  T foundChild = null;

  int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
  for (int i = 0; i < childrenCount; i++)
  {
    var child = VisualTreeHelper.GetChild(parent, i);
    // If the child is not of the request child type child
    T childType = child as T;
    if (childType == null)
    {
      // recursively drill down the tree
      foundChild = FindChild<T>(child, childName);

      // If the child is found, break so we do not overwrite the found child. 
      if (foundChild != null) break;
    }
    else if (!string.IsNullOrEmpty(childName))
    {
      var frameworkElement = child as FrameworkElement;
      // If the child's name is set for search
      if (frameworkElement != null && frameworkElement.Name == childName)
      {
        // if the child's name is of the request name
        foundChild = (T)child;
        break;
      }
    }
    else
    {
      // child element found.
      foundChild = (T)child;
      break;
    }
  }

  return foundChild;
}

因此,在您的命令中,您只需要执行以下操作:

FindChild<ComboBox>(ListView, "resourcetypeSrch")

用您正在查看的数据的父控件的名称替换“ListView”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM