Определение входных привязок в стиле - PullRequest
20 голосов
/ 18 апреля 2010

Я создаю приложение WPF с использованием шаблона проектирования MVVM и пытаюсь расширить элемент управления TabItem, чтобы он закрывал вкладку, когда пользователь нажимает среднюю кнопку мыши. Я пытаюсь добиться этого с помощью InputBindings, и он работает очень хорошо, пока я не попытаюсь определить его в стиле. Я узнал, что вы не можете добавить InputBindings к стилю, если вы не присоедините его с помощью DependencyProperty. Так что я следовал за этим похожим постом здесь ... , и это работает ... почти. Я могу закрыть одну вкладку с помощью средней кнопки мыши, но она не будет работать ни на одной из других вкладок (все вкладки добавляются во время выполнения и наследуют один и тот же стиль).

Так что мне нужна помощь. Почему это работает только в первый раз, а не после? Очевидно, что я мог бы создать собственный элемент управления, который наследовал бы от TabItem, и заставить его работать, но я хотел бы выяснить это, поскольку я вижу, как это расширяется в моих проектах. Я не эксперт по DependencyProperties, поэтому, пожалуйста, помогите мне. Спасибо!

Стиль:

<Style TargetType="{x:Type TabItem}">
    <Setter Property="w:Attach.InputBindings">
        <Setter.Value>
            <InputBindingCollection>
                <MouseBinding MouseAction="MiddleClick" 
                              Command="{Binding CloseCommand}"/>
            </InputBindingCollection>
        </Setter.Value>
    </Setter>
    ...
</Style>

Класс * * 1 010

public class Attach
{
    public static readonly DependencyProperty InputBindingsProperty =
        DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(Attach),
        new FrameworkPropertyMetadata(new InputBindingCollection(),
        (sender, e) =>
        {
            var element = sender as UIElement;
            if (element == null) return;
            element.InputBindings.Clear();
            element.InputBindings.AddRange((InputBindingCollection)e.NewValue);
        }));

    public static InputBindingCollection GetInputBindings(UIElement element)
    {
        return (InputBindingCollection)element.GetValue(InputBindingsProperty);
    }

    public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings)
    {
        element.SetValue(InputBindingsProperty, inputBindings);
    }
}

Ответы [ 2 ]

16 голосов
/ 18 октября 2011

Ваш класс "Attach" отлично сработал для меня! Если кому-то нужно, уловка заключается в использовании такого стиля с модификатором x: Shared:

<InputBindingCollection x:Key="inputCollection" x:Shared="False">
        <KeyBinding Key="Del" Command="{Binding DeleteItemCommand}"/>
</InputBindingCollection>

<Style TargetType="{x:Type TabItem}">
    <Setter Property="w:Attach.InputBindings" Value="{StaticResource inputCollection}" />
    ...
</Style>

Спасибо! * * 1004

14 голосов
/ 19 апреля 2010

Неважно, я сам понял. В итоге я даже не использовал класс Attach выше ... вместо этого я использовал InputBindings на ControlTemplate для TabItem (который является границей), так что это выглядело примерно так ... Я не знаю, почему я не думал об этом в первую очередь ..:)

<ControlTemplate TargetType="{x:Type TabItem}">
    <Grid SnapsToDevicePixels="true">
        <Border x:Name="Bd" ...>
            <DockPanel>
                ...
            </DockPanel>
            <Border.InputBindings>
                <MouseBinding MouseAction="MiddleClick"
                              Command="{Binding CloseCommand}"/>
            </Border.InputBindings>
        </Border>
    </Grid>
    ...
</ControlTemplate>
...