Определение InputBindings в стиле
Я создаю приложение 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>
Класс
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);
}
}
Ответы
Ответ 1
Ничего, я сам это понял. Я закончил тем, что даже не использовал класс 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>
Ответ 2
Ваш класс "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>
Спасибо!