开发者

Defining InputBindings within a Style

开发者 https://www.devze.com 2022-12-27 01:34 出处:网络
I\'m creating a WPF app using the MVVM design pattern, and I\'m trying to extend the TabItem control so that it closes the tab when the user clicks the middle mouse button. I\'m trying to achieve this

I'm creating a WPF app using the MVVM design pattern, and I'm trying to extend the TabItem control so that it closes the tab when the user clicks the middle mouse button. I'm trying to achieve this using InputBindings, and it works very well until I try to define it within a style. I've learned that you cannot add InputBindings to a style unless you attach it using a DependencyProp开发者_C百科erty. So I followed this similar post here... and it works... almost. I can close one tab using the middle mouse button, but it won't work on any of the other tabs (all of the tabs are added at runtime and inherit the same style).

So I need some help. Why would this only be working the first time, and not after? Obviously I could create a custom control that inherits from a TabItem and make it work, but I'd like to figure this out as I can see this being expanded in my projects. I'm no expert on DependencyProperties, so please help me out. Thanks!

Style:

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

Class

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);
    }
}


Your class "Attach" worked fine for me! If anyone needs, the trick is use style like this, with the x:Shared modifier:

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

Thanks!


Never mind, I figured it out myself. I ended up not even using the Attach class above... instead I used InputBindings on the ControlTemplate for the TabItem (which is a Border), so it looked something like this... I don't know why I didn't think of this in the first place.. :)

<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>
0

精彩评论

暂无评论...
验证码 换一张
取 消