3

私が現在取り組んでいるコントロールでは、アイテムがフォーカスされている場合、デフォルトのフォーカス四角形は行全体とそのすべての表示可能な子アイテムにまたがっています。私はそれを隠す方法を知っています。しかし、アイテムにキーボード フォーカスがある場合は、そのようなフォーカス インジケーターが必要です。IsKeyboardFocused プロパティについて読みましたが、アイテムがマウスでクリックされた場合にも当てはまります。だから、どうにかして FocusVisualStyle を使用する必要があると思います。しかし、私は方法を理解できません。

デフォルトのフォーカスは次のようになります。

ここに画像の説明を入力

そして、これはそれが好きであるべきものです:

ここに画像の説明を入力

コントロール テンプレートの XAML コードは次のとおりです。

<Border ...>
    <ContentPresenter FocusManager.IsFocusScope="True"
        Content="{TemplateBinding HeaderedContentControl.Header}"
        ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
        ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
        ContentSource="Header"
        Name="PART_Header" .../>
</Border>
<!-- Additional border glare inside the item -->
<Border BorderThickness="1" BorderBrush="#80ffffff" Margin="1"
    SnapsToDevicePixels="True" CornerRadius="2"/>
<!-- Focus rectangle inside the item -->
<Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="Black"
    SnapsToDevicePixels="True" Margin="2"
    Visibility="Hidden" Name="FocusRectangle"
    FocusVisualStyle="{StaticResource FocusStyle}"/>

私の XAML には、既定では表示されないフォーカス四角形が既にあります。FocusVisualStyle などを使用して、可視にする必要があります。しかし、私はそれをすることができませんでした。どの焦点でも見えるか、まったく見えないかのどちらかです。

4

1 に答える 1

0

この問題の回避策を見つけました。私には同じように見えますが、それが正しい方法であるかどうかは完全にはわかりません。私は上から FocusRectangle を使用しており、それを自分で表示および非表示にしています。

フォーカス四角形の可視性を管理するトリガーは次のとおりです。

<!-- Show the focus rectangle when the item is focused -->
<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="Controls:TreeViewExItem.IsKeyboardMode" Value="True"/>
    <Condition Property="Controls:TreeViewExItem.IsFocused" Value="True"/>
  </MultiTrigger.Conditions>
  <Setter TargetName="FocusRectangle" Property="Visibility" Value="Visible"/>
</MultiTrigger>

次に、最後の入力がマウスまたはキーボードのどちらから来たかを示す新しいプロパティを TreeViewExItem に追加しました。これはおそらくタッチまたはスタイラスに拡張される可能性がありますが、テストするそのようなデバイスはありません.

public static DependencyProperty IsKeyboardModeProperty =
    DependencyProperty.Register(
        "IsKeyboardMode",
        typeof(bool),
        typeof(TreeViewExItem),
        new FrameworkPropertyMetadata(false, null));

public bool IsKeyboardMode
{
    get
    {
        return (bool) GetValue(IsKeyboardModeProperty);
    }
    set
    {
        SetValue(IsKeyboardModeProperty, value);
    }
}

このプロパティは、バインディングを通じて親コントロールから各項目に渡されます。

<!-- Pass on the TreeViewEx' IsKeyboardMode value to each item because
  we couldn't access it otherwise in the triggers -->
<Setter Property="IsKeyboardMode"
  Value="{Binding (Controls:TreeViewEx.IsKeyboardMode),
    RelativeSource={RelativeSource
      AncestorType={x:Type Controls:TreeViewEx}}, Mode=OneWay}" />

同じ IsKeyboardMode プロパティが TreeViewEx 親コントロールに追加され、ここに私の魔法があります。

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
    base.OnPreviewKeyDown(e);
    if (!IsKeyboardMode)
    {
        IsKeyboardMode = true;
        //Debug.WriteLine("Changing to keyboard mode from PreviewKeyDown");
    }
}

protected override void OnPreviewKeyUp(KeyEventArgs e)
{
    base.OnPreviewKeyDown(e);
    if (!IsKeyboardMode)
    {
        IsKeyboardMode = true;
        //Debug.WriteLine("Changing to keyboard mode from PreviewKeyUp");
    }
}

protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
    base.OnPreviewMouseDown(e);
    if (IsKeyboardMode)
    {
        IsKeyboardMode = false;
        //Debug.WriteLine("Changing to mouse mode");
    }
}

これは、キーボードとマウスのプレビュー イベントに反応して、適切な入力モードを設定します。最後の入力がキーボードからのものである場合にのみ、フォーカス四角形が表示されます。

于 2012-07-31T21:00:25.953 に答える