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