在KeyBinding中将Control绑定为CommandParameter

时间:2016-04-01 20:32:18

标签: c# wpf xaml

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

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

  

尝试引用尚未命名的命名对象'resourcetypeSrch'   尚未定义。转发引用或对对象的引用   包含前向引用,不支持除指令之外的指令   键。

如何将带有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>

3 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

我相信您希望能够通过标签浏览网格标题中的控件。你可以做的是在dataSource中为每一列创建一个属性(即Column1IsFocused,Column2IsFocused)。

然后,您可以创建一个扩展来聚焦您的控件(例如here is one)来自viewmodel。您将扩展的属性IsFocused绑定到dataSource中的每个属性,然后在Command处理程序中将一个或另一个属性设置为true。我相信这可能有用。

答案 2 :(得分:0)

我只想到另一个可能性。您可以在命令处理程序方法中遍历可视树,并按名称查找控件。这是一个方法的一个很好的实现,它通过一个对象的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”替换为您正在查找的数据的父控件的名称。