WPF:动态视图/内容

3
我对WPF还是有些初学者,所以想问一下...
假设我有一个窗口,在窗口内部我想要有像容器一样的东西,可以是边框或者面板(在Winform中的术语)。容器的内容绑定到所选选项(例如:按钮)。例如,当用户选择选项1时,容器显示图表;当用户选择选项2时,容器显示填充有数据的列表视图;当用户选择选项3时,容器显示其他内容,依此类推。
什么是最好/最好看(或最简单)的方法来实现这个?我正在考虑使用用户控件作为容器内容,但不知道这是否是一个好的解决方案,也不知道使用用户控件来显示有点复杂的东西和可能的一些计算的性能。还有其他想法吗?
illustration: https://istack.dev59.com/eWpBj.webp

1
您可以使用 ContentPresenter 并根据所选选项更改内容。 - sa_ddam213
您可以将任何View/XAML放置在Content中。许多MVVM框架(我使用ReactiveUI)都具有强大的选择ViewModel和View的切换容器。编辑:请看这里https://dev59.com/K2_Xa4cB1Zd3GeqP2IYP - kenny
能否给出解释?或者在新的回答中说明。 - bagz_man
3个回答

4
我使用了一个ContentControl来解决这个问题。
主窗口: (将您想要可视化的视图定义为资源)
<Window.Resources>
    <DataTemplate DataType="{x:Type viewModels:SystemPCViewModel}">
        <controls:SystemPCControl/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type viewModels:ChipPCViewModel}">
        <controls:ChipPCControl/>
    </DataTemplate>
    </ResourceDictionary>

</Window.Resources>

<Grid>
   <ContentControl Content="{Binding CurrentView}"/>
</Grid>

ViewModel:(简单易懂的解释)

public ViewModelBase CurrentView
{
    get { return currentView; }
    set { Set(() => CurrentView, ref currentView, value); }
}

接下来,您可以通过为您在MainWindow中定义的控件设置视图模型来更改视图。

private void OnCommandExecuted()
{
    CurrentView = someViewModel;
}

private void OnAnotherCommandExecuted()
{
    CurrentView = anotherViewModel;
}

HTH!


4
为了详细说明 @Sheridan 的答案,这里提供一个简单的 XAML 代码片段,使用 TabControl 实现了你所需要的功能:
<TabControl TabStripPlacement="Left">

        <TabItem Header="Option 1">
            <Grid Background="DarkGray">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 1"/>
            </Grid>
        </TabItem>

        <TabItem Header="Option 2">
            <Grid Background="DarkBlue">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 2"/>
            </Grid>
        </TabItem>

        <TabItem Header="Option 3">
            <Grid Background="DarkSlateBlue">
                <TextBlock Foreground="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="20" Text="View 3"/>
            </Grid>
        </TabItem>

    </TabControl>

结果:

在此输入图片描述

您可以通过将以下简单的Style添加到Window.Resources中对其进行一些自定义:

 <Window.Resources>
        <Style TargetType="TabItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TabItem">
                        <RadioButton Content="{TemplateBinding Header}" Margin="2"
                                     IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

这将导致:

enter image description here

“WPF Mentality”让您从功能而非外观的角度思考UI控件,这就是TabControl=)。


肯定可以被接受的。 无论如何,我还在等待另一种方法..也许使用ContentPresenter / ContentControl。 - bagz_man
@bagz_man TabControl 的默认模板已经包含了一个 ContentPresenter。你为什么要重复造轮子呢?另外,我的方法有什么问题吗? - Federico Berasategui
你的方法确实非常好,我+1了它。我只是在考虑另一种方法,使用ContentControl和ContentPresenter。 因为我认为我们可以将选项与内容分开,我的意思是它们之间有一些空间,并且更灵活。但如果您能给出在选项卡带和内容之间添加空间的示例,那就太好了。 - bagz_man

1
你所描述的内容与标准的TabControl非常相似,但使用了一个控件模板(ControlTemplate),将选项卡放在内容面板上方而不是左侧。使用这种方法意味着每个TabItem中都有一个UserControl,即多个控件。您可以从MSDN的TabControl类页面TabControl Class了解更多关于TabControl的信息。

不,我不是指选项卡容器,因为我要实现的只是一个(仅有一个)显示动态内容的容器。 - bagz_man

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接