如何切换StackPanel项目' Panel.ZIndex值与Control外?

时间:2015-12-07 07:31:26

标签: c# wpf xaml

也许这是一个愚蠢的问题,但我只是想知道如何设计这种布局:

首先,我有一个MenuList ObservableCollection。所以我必须将这些菜单放入stackPanel,如下所示:

<Window.Resources>
    <DataTemplate x:Key="MenuItemTemplate">
        <Button Content="{Binding ContentText}" Panel.ZIndex="{Binding PIndex}" Padding="10" FontSize="20"/>
    </DataTemplate>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

所以它看起来像这样: enter image description here

一段时间后,在此菜单下添加了一个新栏:

<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
    .......
</ItemsControl>

<Border Background="Green" VerticalAlignment="Top" Panel.ZIndex="10" Height="30" Margin="0,81,0,0"/>

现在它看起来像这样:

enter image description here

要求是,如果选择了一个按钮,它应该在栏的顶部,其他未选择的按钮应该被栏覆盖:

enter image description here

但按钮&#39;在StackPanel中,所以它们都基于StackPanel的ZIndex。

我的问题是,如何在xaml中设计这样的布局?

3 个答案:

答案 0 :(得分:0)

如果条形图只是一个绿色条形图,您也可以将它作为单独的Stackpanel放在DataTemplate上,然后在Button的stackpanel上放置一个Style.Trigger来增加ZIndex OnMouseOver。即使只是重复,酒吧也会看起来无缝。

所以而不是:

<DataTemplate x:Key="MenuItemTemplate">
    <Button Content="{Binding ContentText}" Panel.ZIndex="{Binding PIndex}" Padding="10" FontSize="20"/>
</DataTemplate>

你将

      <DataTemplate x:Key="MenuItemTemplate">
        <Grid>
        <StackPanel >
                <StackPanel.Style>
                    <Style TargetType="StackPanel" >
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Panel.ZIndex" Value="3"></Setter>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="False">
                                <Setter Property="Panel.ZIndex" Value="1"></Setter>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </StackPanel.Style>
        <Button Width="100" Height="100" Content="{Binding ContentText}" Padding="10" FontSize="20" />
        </StackPanel>
        <StackPanel Panel.ZIndex="2">
            <Border Background="Green" VerticalAlignment="Top" Height="30"/>
        </StackPanel>
        </Grid>
    </DataTemplate>

(如果你运行它,这看起来并不完美,但你明白了)

答案 1 :(得分:0)

我认为使用renderTransform更好。无需在xaml中硬编码PIndex。见下文。

<DataTemplate x:Key="MenuItemTemplate">
      <Button Content="{Binding}" Padding="10" FontSize="20" Height="30"   Width="100">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <Trigger Property="IsFocused" Value="True">
                            <Setter Property="RenderTransform">
                                <Setter.Value>
                                    <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1" ScaleY="1.2"></ScaleTransform>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
</DataTemplate>

<Border Background="Green" VerticalAlignment="Top"  Height="30"  Margin="0,150,0,0"/>
<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
 </ItemsControl>

代码背后:

public ObservableCollection<string> Menus { get; set; }

编辑:

<DataTemplate x:Key="MenuItemTemplate">
        <Button Content="{StaticResource image1}" Height="30" Width="100">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Grid>
                                    <Border x:Name="Border" Height="{TemplateBinding Height}"
                                        Width="{TemplateBinding Width}" Background="Orange">
                                    </Border>
                                    <ContentPresenter ContentSource="Content" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsFocused" Value="True">
                                        <Setter Property="RenderTransform"  TargetName="Border">
                                            <Setter.Value>
                                                <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1" ScaleY="1.2"></ScaleTransform>
                                            </Setter.Value>
                                        </Setter>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>

                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </DataTemplate>

答案 2 :(得分:0)

  1. Dockpanel作为我们的ItemPanelTemplate是正确的选择。

  2. 使用带有按钮和矩形的网格(用于底部边框)作为DataTemplate来显示菜单项。

  3. 在上面的第2步中,不要在DataTemplate的网格中应用保证金。而是使用Grid Padding,Button margin作为间距。

  4. DataTemplate:

    <DataTemplate x:Key="MenuItemTemplate">
        <Grid Background="DodgerBlue">
            <Button Margin="5 5 5 0" HorizontalAlignment="Left" Panel.ZIndex="1" Content="{Binding ContentText}" Padding="1"  Width="75" GotKeyboardFocus="Button_GotKeyboardFocus" LostKeyboardFocus="Button_LostKeyboardFocus"/>
            <Rectangle  Panel.ZIndex="2" Fill="BurlyWood" Height="5" Margin="0 25 0 0"/>
        </Grid>
    </DataTemplate>
    

    ItemPanelTemplate:

    <ItemsPanelTemplate>
        <DockPanel Height="30" LastChildFill="True"/>
    </ItemsPanelTemplate>
    

    按原样使用以下代码:

    <ItemsControl Panel.ZIndex="10" VerticalAlignment="Top" ItemsSource="{Binding Menus}" ItemTemplate="{DynamicResource MenuItemTemplate}" Margin="0">
        <ItemsControl.Resources>
            <DataTemplate x:Key="MenuItemTemplate">
                <Grid Background="DodgerBlue">
                    <Button Margin="0" HorizontalAlignment="Left" Panel.ZIndex="1" Content="{Binding ContentText}" Padding="1"  Width="75" GotKeyboardFocus="Button_GotKeyboardFocus" LostKeyboardFocus="Button_LostKeyboardFocus"/>
                    <Rectangle  Panel.ZIndex="2" Fill="BurlyWood" Height="5" Margin="0 25 0 0"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.Resources>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <DockPanel Height="30" LastChildFill="True"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl> 
    

    代码隐藏

    public IList Menus { get; set; }
    public Window1()
    {
        InitializeComponent();
    
        Menus = new[] { new { ContentText = "Menu1" }, new { ContentText = "Menu2" }, new { ContentText = "Menu3" } };
    
        this.DataContext = this;
    }
    
    
    private void Button_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        Panel.SetZIndex((Button)e.OriginalSource, 12);
    }
    
    private void Button_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        Panel.SetZIndex((Button)e.OriginalSource, 1);
    }
    

    spring:url