WPF中的QStackedLayout等价物

时间:2011-11-02 20:13:48

标签: wpf qt

我是一位经验丰富的Qt程序员,我使用QStackedLayout在主窗口中显示不同的小部件。有人可以指点我在WPF中的等效构造:是否有像QStackedLayout这样的东西?如果没有,WPF中如何使用这种模式?

基本上我有一个WPF功能区应用程序,如果切换功能区组,相应的“小部件”/ XAML应显示在剩余区域(“内容”)中。

谢谢,伙计。

2 个答案:

答案 0 :(得分:0)

没有本机面板或控件可以做到这一点,但您可以利用TabControl来完成它。您需要使用自定义样式,尽管如此:

<Style x:Key="NoTabsTabControlStyle" TargetType="{x:Type TabControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        KeyboardNavigation.TabNavigation="Local"
                        KeyboardNavigation.DirectionalNavigation="Contained">
                    <ContentPresenter x:Name="PART_SelectedContentHost"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                      Margin="{TemplateBinding Padding}"
                                      ContentSource="SelectedContent"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" 
                             Value="false">
                        <Setter Property="Foreground" 
                                Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后使用它:

<TabControl Style="{StaticResource NoTabsTabControlStyle}">
    <TabItem Content="One" />
    <TabItem Content="Two" />
</TabControl>

然后要显示一组内容,您需要在TabControl上设置SelectedIndex。

答案 1 :(得分:0)

对于主题入门者来说有点迟,但对于那些来我这里寻找WPF版本的QStackedLayout的人来说可能会有所帮助,就像我一样。

我使用了非常简化的WPF布局示例实现,几乎丢弃了所有布局。 该组件基于StackLayout,允许简单的视觉设计,在设计时它就像普通的堆栈面板一样。

using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;

namespace org.tequilacat.stacklayout {

    /// <summary>
    /// QStackedLayout implementation for WPF
    /// only one child is displayed extended to the panel size.
    /// In design time it behaves like stack panel
    /// </summary>
    public class StackLayoutPanel : StackPanel {

        private bool isDesignTime() {
            return System.ComponentModel.DesignerProperties.GetIsInDesignMode(this);
        }

        private bool useBaseBehaviour() {
            return isDesignTime();
        }

        // in runtime just return the given arg
        protected override Size MeasureOverride(Size availableSize) {
            if (useBaseBehaviour()) {
                return base.MeasureOverride(availableSize);
            }

            return availableSize;
        }

        // in runtime arrange all children to the given arg
        protected override Size ArrangeOverride(Size finalSize) {
            if (useBaseBehaviour()) {
                return base.ArrangeOverride(finalSize);
            }

            foreach (UIElement child in InternalChildren) {
                child.Arrange(new Rect(finalSize));
            }

            return finalSize;
        }
    }
}

XAML

<Window ... xmlns:uilib="clr-namespace:org.tequilacat.stacklayout">

  <uilib:StackLayoutPanel >
    <StackPanel Name="projectPropertyPanel"> ... </StackPanel>
    <StackPanel Name="configurationPanel"> ... </StackPanel>
    <StackPanel Name="casePanel"> ... </StackPanel>
  </uilib:StackLayoutPanel>

在运行时,可见组件通过Visibility属性选择(这取决于我的业务逻辑,uiState可以采用3个值激活其中一个面板)。它是非常基本的,可以实现自己的CurrentPage属性左右,我只是保持简单:

projectPropertyPanel.Visibility = (uiState == UiState.ProjectProperties) ? 
  Visibility.Visible : Visibility.Collapsed;
configurationPanel.Visibility = (uiState == UiState.ConfigurationSelected) ? 
  Visibility.Visible : Visibility.Collapsed;
casePanel.Visibility = (uiState == UiState.CaseSelected) ? 
  Visibility.Visible : Visibility.Collapsed;