Привязка пользовательского присоединенного свойства и OnSetPropertyCallback - PullRequest
0 голосов
/ 17 июля 2010

У окна есть MenuItem, связанный с коллекцией, MenuItem имеет ItemTemplate, который содержит другой MenuItem с прикрепленным свойством, использующим привязку:

<Menu Background="Transparent">
        <MenuItem ItemsSource="{Binding SomeThings}" Header="Menu">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding MenuTitle}" WpfApplication30:MainWindow.KeyGesture="{Binding KeyGesture}"/>
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
    </Menu>

Объявление источника данных и прикрепленного свойства:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        DataContext = new { 
            SomeThings = new[]
                {
                    new { MenuTitle = "Title 1", KeyGesture = new KeyGesture(Key.A, ModifierKeys.Control) }, 
                    new { MenuTitle = "Title 2", KeyGesture = new KeyGesture(Key.B, ModifierKeys.Control) }, 
                    new { MenuTitle = "Title 3", KeyGesture = new KeyGesture(Key.C, ModifierKeys.Control) }, 
                } };
    }

    public static string GetKeyGesture(MenuItem obj)
    {
        return (string)obj.GetValue(KeyGestureProperty);
    }

    public static void SetKeyGesture(MenuItem obj, string value)
    {
        obj.SetValue(KeyGestureProperty, value);
    }

    public static readonly DependencyProperty KeyGestureProperty =
        DependencyProperty.RegisterAttached("KeyGesture", typeof(KeyGesture), typeof(MainWindow), 
            new PropertyMetadata(OnSetKeyGestureCallback));

    private static void OnSetKeyGestureCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var window = GetWindow(dependencyObject);
        var keyGesture = (KeyGesture)e.NewValue;
        window.KeyDown += (sender, keyArgs) =>
        {
            if (keyArgs.Key == keyGesture.Key && keyArgs.KeyboardDevice.Modifiers == keyGesture.Modifiers)
            {
                window.Background = Brushes.AntiqueWhite;
            }
        };

    }

После вызова OnSetKeyGestureCallback пользователь может использовать ярлык для выполнения действия. Но OnSetKeyGestureCallback вызывается только после открытия меню. Таким образом, пока пользователь не откроет меню, ярлыки недоступны. Как сделать так, чтобы OnSetKeyGestureCallback вызывался сразу после загрузки окна или меню?

Ответы [ 2 ]

0 голосов
/ 18 июля 2010

Не нужно решение этой проблемы. Сделал другую реализацию для ярлыков.

0 голосов
/ 17 июля 2010

Ваш DataTemplate для MenuItem содержит MenuItem.Следовательно, у вас будет два MenuItem в вашем визуальном дереве, один дочерний от другого.Свойства дочернего элемента будут установлены правильно, а родительский - нет.

Если вам нужно указать свойство в MenuItem, вы должны использовать ItemContainerStyle:

<MenuItem ItemsSource="{Binding SomeThings}" Header="Menu">
    <MenuItem.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding MenuTitle}"/>
            <Setter Property="MainWindow.KeyGesture" Value="{Binding KeyGesture}"/>
        </Style>
    </MenuItem>
</MenuItem>

Что касается того, почему ваше соединение не работает до тех пор, пока Menu не будет открыто, это потому, что дочерние элементы Menu виртуализированы и не создаются до тех пор, пока не потребуется (т. Е. Пока не будет открыт родительский элемент Menu).Вы также можете переопределить Panel, используемый для размещения дочерних элементов:

<MenuItem>
    <MenuItem.ItemContainerStyle>
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding MenuTitle}"/>
            <Setter Property="MainWindow.KeyGesture" Value="{Binding KeyGesture}"/>
        </Style>
    </MenuItem>
    <MenuItem.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </MenuItem.ItemsPanel>
</MenuItem>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...