Коллекция элементов привязки в меню для отображения во всплывающем меню MenuItem - PullRequest
0 голосов
/ 15 октября 2018

Мне нужно иметь собственное меню (класс AMTMenu, унаследованный от Menu, а также некоторые дополнительные свойства DependencyProperties) с MenuItem (фактически кнопка гамбургера) с динамическими дочерними элементами, поскольку это меню должно использоваться во многих макетах.Кроме этого, он должен отображать 5 других пунктов меню TopLevel, которые отображают информацию, содержащуюся в DataContext без дочерних элементов, и кнопку обновления.Он работает нормально, за исключением части подменю, которая не отображается, когда я щелкаю гамбургер MenuItem, потому что я не могу правильно связать элементы.Вот код, который у меня пока есть:

<Menu.Template>
    <ControlTemplate>
        <Grid Name="ContentGrid"
              Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
              IsItemsHost="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="HamburgerButtonColumn" Width="5*" />
                <ColumnDefinition x:Name="ButtonsColumn" Width="90*" />
                <ColumnDefinition x:Name="RefreshButtonColumn" Width="5*"/>
            </Grid.ColumnDefinitions>
            <MenuItem Foreground="{DynamicResource BlackBrush}"
                      Focusable="False"
                      Template="{DynamicResource MainMenuButtonTemplate}">
                <MenuItem.Icon>
                    <iconPacks:PackIconMaterial Kind="Menu"
                                                HorizontalAlignment="Left"
                                                VerticalAlignment="Center"
                                                MinHeight="20" />
                </MenuItem.Icon>
            </MenuItem>
            <UniformGrid Name="ButtonsUniformGrid"
                         Grid.Column="1"
                         Columns="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:AMTMenu}}, Path=ButtonCount}"
                         Rows="1"
                         HorizontalAlignment="Stretch">
                <MenuItem Grid.Column="0"
                          Template="{DynamicResource OiButtonsTemplate}"
                          Foreground="{Binding RelativeSource={RelativeSource Self}, Path=Tag, Converter={StaticResource OiMainMenuButtonsColorBrushConverter}}"
                          Focusable="False"
                          Command="{Binding ShowRefreshDataCommand}"
                          CommandParameter="Button1">
                    <MenuItem.Tag>
                        <MultiBinding Converter="{StaticResource MainMenuButtonsTextConverter}" ConverterParameter="INC">
                            [ ... MultiBinding logic ... ]
                        </MultiBinding>
                    </MenuItem.Tag>
                </MenuItem>

                [ ... XAML Code for the other 4 MenuItems ... ]

            </UniformGrid>
            <DockPanel Name="PART_Refresh"
                       Grid.Column="2"
                       HorizontalAlignment="Stretch"
                       VerticalAlignment="Stretch">

                [ ... XAML Code for the refresh button ... ]

            </DockPanel>
        </Grid>
    </ControlTemplate>
</Menu.Template>

Что касается гамбургера MenuItem, у меня есть следующий шаблон:

<ControlTemplate x:Key="MainMenuButtonTemplate"
                 TargetType="{x:Type MenuItem}">
    <Grid SnapsToDevicePixels="true"
          HorizontalAlignment="Stretch">
        <StackPanel Background="{TemplateBinding Background}"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center">
            <ContentControl x:Name="PART_Button"
                            Foreground="{TemplateBinding Foreground}"
                            Background="{TemplateBinding Background}"
                            Content="{TemplateBinding Icon}"
                            Focusable="False" />
        </StackPanel>
        <Popup x:Name="PART_Popup" 
               AllowsTransparency="true"
               Focusable="false"
               HorizontalOffset="1"
               IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
               PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
               Placement="Bottom"
               VerticalOffset="-1">
            <Border BorderThickness="2"
                    BorderBrush="White"
                    Background="{TemplateBinding Background}">
                <ScrollViewer x:Name="SubMenuScrollViewer"
                              CanContentScroll="true"
                              Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                    <Grid RenderOptions.ClearTypeHint="Enabled">
                        <ItemsPresenter x:Name="ItemsPresenter"
                                        KeyboardNavigation.DirectionalNavigation="Cycle"
                                        Grid.IsSharedSizeScope="true"
                                        Margin="2"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                        KeyboardNavigation.TabNavigation="Cycle"/>
                    </Grid>
                </ScrollViewer>
            </Border>
        </Popup>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="{DynamicResource AccentColorBrush}" TargetName="PART_Button"/>
            <Setter Property="Background" Value="{DynamicResource GrayBrush}" TargetName="PART_Button"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Наконец, я объявляю Меню и подменю с помощьюследующий XAML:

<local:AMTMenu x:Name="MainMenu"
                   DockPanel.Dock="Top"
                   DataContext="{Binding CurrentModel}"
                   IsButton1Visible="True"
                   IsButton2Visible="True"
                   IsButton3Visible="True"
                   IsButton4Visible="True"
                   IsButton5Visible="False">
    <MenuItem Header="Item 1" />
    <Separator />
    <MenuItem Header="Item 2" />
    <Separator />
    <MenuItem Header="Item 3" />
</local:AMTMenu>

Как я могу связать коллекцию Предметов в Меню, которая будет показана во всплывающем окне Гамбургера MenuItem?

1 Ответ

0 голосов
/ 17 октября 2018

Итак, я нашел проблему, разместив здесь, чтобы помочь всем, у кого есть подобная проблема ... Проблема заключалась в том, что в шаблоне был объявлен гамбургер MenuItem, поэтому у меню не было дочерних элементов и, следовательно, не было запущено IsSubmenuOpen.свойство на MenuItem.После того, как я понял это, решение было довольно простым, заменил MenuItem в шаблоне на ItemsPresenter и переместил MenuItem в содержимое меню.Кроме того, и поскольку в меню теперь есть элементы, определенные в его классе, я не могу объявить подменю, как я делал ранее, оно заменит только мой элемент по умолчанию, поэтому мне пришлось использовать новый DependencyProperty с именем SubMenuItems.

Вот окончательный код:

AMTMenu.xaml

<Menu>
    <Menu.Template>
        <ControlTemplate>
            <Grid Name="ContentGrid"
                  Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
                  IsItemsHost="True">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition x:Name="HamburgerButtonColumn" Width="5*" />
                    <ColumnDefinition x:Name="ButtonsColumn" Width="90*" />
                    <ColumnDefinition x:Name="RefreshButtonColumn" Width="5*"/>
                </Grid.ColumnDefinitions>
                <ItemsPresenter x:Name="ItemsPresenter"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                KeyboardNavigation.DirectionalNavigation="Cycle"
                                Grid.IsSharedSizeScope="true"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                KeyboardNavigation.TabNavigation="Cycle" />
                <UniformGrid Name="ButtonsUniformGrid"
                             Grid.Column="1"
                             Columns="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:AMTMenu}}, Path=ButtonCount}"
                             Rows="1"
                             HorizontalAlignment="Stretch">
                    <MenuItem Grid.Column="0"
                              Template="{DynamicResource OiButtonsTemplate}"
                              Foreground="{Binding RelativeSource={RelativeSource Self}, Path=Tag, Converter={StaticResource OiMainMenuButtonsColorBrushConverter}}"
                              Focusable="False"
                              Command="{Binding ShowRefreshDataCommand}"
                              CommandParameter="Button1">
                        <MenuItem.Tag>
                            <MultiBinding Converter="{StaticResource MainMenuButtonsTextConverter}" ConverterParameter="INC">
                                [ ... MultiBinding logic ... ]
                            </MultiBinding>
                        </MenuItem.Tag>
                    </MenuItem>

                    [ ... XAML Code for the other 4 MenuItems ... ]

                </UniformGrid>
                <DockPanel Name="PART_Refresh"
                           Grid.Column="2"
                           HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch">

                    [ ... XAML Code for the refresh button ... ]

                </DockPanel>
            </Grid>
        </ControlTemplate>
    </Menu.Template>
    <MenuItem Foreground="{DynamicResource BlackBrush}"
              Focusable="False"
              Template="{DynamicResource MainMenuButtonTemplate}"
              AllowDrop="True"
              ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:AMTMenu}, Path=SubMenuItems}">
        <MenuItem.Icon>
            <iconPacks:PackIconMaterial Kind="Menu" MinHeight="20" />
        </MenuItem.Icon>
    </MenuItem>
</Menu>

Объявление меню в родительском представлении:

<local:AMTMenu x:Name="MainMenu"
               DockPanel.Dock="Top"
               DataContext="{Binding CurrentModel}"
               IsButton1Visible="True"
               IsButton2Visible="True"
               IsButton3Visible="True"
               IsButton4Visible="True"
               IsButton5Visible="False">
    <local:AMTMenu.SubMenuItems>
        <local:SubMenuItemsCollection>
            <MenuItem Header="Item 1" />
            <Separator />
            <MenuItem Header="Item 2" />
            <Separator />
            <MenuItem Header="Item 3" />
        </local:SubMenuItemsCollection>
    </local:AMTMenu.SubMenuItems>
</local:AMTMenu>

Где SubMenuItemsCollection - это просто класс, производный отObservableCollection

public class SubMenuItemsCollection : ObservableCollection<FrameworkElement> { }

Надеюсь, это поможет кому-то в будущем;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...