如何在一个 xaml 页面中使用多个用户控件?
Posted
技术标签:
【中文标题】如何在一个 xaml 页面中使用多个用户控件?【英文标题】:How do I use multiple user-controls inside one xaml page? 【发布时间】:2019-09-26 21:40:55 【问题描述】:我正在创建一个用于教育目的的应用程序。如何在“MainWindow.xaml”中使用多个用户控件?
我想在我的 MainWindow 上使用用户控件,这样我就不需要多个窗口。因此,在您在注册布局上按下一步后,
它应该带你到感谢屏幕,这也是另一个 UserControl 类。虽然在同一个窗口。
我已经阅读了尽可能多的不同“解决方案”,但没有任何真正的运气......
这是我的自动取款机代码。
主窗口.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="700"
WindowStartupLocation="CenterScreen">
<Grid>
<!--Background image-->
<Grid.Background >
<ImageBrush ImageSource="login-page-background-3.jpg"/>
</Grid.Background>
<!--Main content scroll-->
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<local:SignUpControl>
</local:SignUpControl>
</ScrollViewer>
</Grid>
MainWindow.xaml.cs没有代码...
SignUpControl.Xaml
<UserControl x:Class="WpfApp1.SignUpControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextBlock.TextAlignment="Center">
<!--Login main content white box-->
<Border Background="WhiteSmoke"
Opacity="0.4"
CornerRadius="30"
Padding="15 50 15 15"
Width="350"
Margin="50 50 50 0">
<StackPanel>
<!--Sign Up header-->
<TextBlock FontSize="20"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Height="auto"
FontFamily="Goudy Stout" >Sign Up</TextBlock>
<!--Sign up subtext-->
<TextBlock FontSize="14"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Height="auto"
FontFamily="Ravie" >It's about to get fun!</TextBlock>
<!--Inner grid for Username & Password-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Textbox for username-->
<TextBox Grid.Row="0" BorderThickness="0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontFamily="Arial" FontWeight="Bold" FontSize="14" x:Name="UsernameBox" Margin="5"/>
<TextBlock IsHitTestVisible="False" Text="Username" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,0,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="14" Foreground="Black">
<TextBlock.Style>
<Style TargetType="x:Type TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="Binding Text, ElementName=UsernameBox" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<!--PasswordBox-->
<TextBox Grid.Row="1" BorderThickness="0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontFamily="Arial" FontWeight="Bold" FontSize="14" x:Name="passwordBox" Margin="5"/>
<TextBlock Grid.Row="1" IsHitTestVisible="False" Text="password" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10,0,0,0" FontFamily="Arial" FontWeight="Bold" FontSize="14" Foreground="Black">
<TextBlock.Style>
<Style TargetType="x:Type TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="Binding Text, ElementName=passwordBox" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
<!--Next Button-->
<Button Content="Next"
HorizontalAlignment="Center"
FontWeight="Bold"
FontSize="14"
BorderThickness="0"
FontFamily="Goudy Stout"
Background="Transparent"
Padding="20 10"
Margin="0 10"
x:Name="NextButton"
Click="NextButton_Click"/>
</StackPanel>
</Border>
<!--Border for PreRegistered account-->
<Border Background="WhiteSmoke"
Opacity="0.4"
CornerRadius="50"
Padding="0"
Width="400"
Height="auto"
Margin="0 12.5 0 0">
<!--Already registered button-->
<Button Content="I already have an account"
HorizontalAlignment="Center"
Opacity="0.8"
FontSize="13"
BorderThickness="0"
FontFamily="Goudy Stout"
Background="Transparent"
Foreground="Black"
x:Name="alreadyRegBtn"
Padding="0 10"
Margin="0 5 0 5"/>
</Border>
</StackPanel>
我该如何做这个解决方案,我可以在同一个窗口上的用户控件之间进行切换,当然,在感谢屏幕之后,我将使用相同的逻辑转到“登录!”等等……
【问题讨论】:
看看页面导航。 【参考方案1】:当我不使用Prism
或Dependency Injection
时,我通常使用视图模型优先方法。
在这种情况下,我们的 Windows ViewModel 上有一个属性,该属性是其他 UserControls
ViewModel 继承自的类,通常只使用具有 INotifyPropertyChanged
隐含的 ViewModelBase 类:
private ViewModelBase currentViewModel;
public ViewModelBase CurrentViewModel
get return currentViewModel;
set currentViewModel = value; NotifyPropertyChanged();
现在在你的MainWindow
里面,就像@Tomtom 说你有一个ContentControl
绑定到那个属性。这意味着使用 DataTemplates
您可以有不同的 View 显示,具体取决于该属性上当前的 ViewModel 类型。
<Window.Resources>
<DataTemplate DataType="x:Type viewmodels:ViewModel1">
<views:View1/>
</DataTemplate>
<DataTemplate DataType="x:Type viewmodels:ViewModel2">
<views:View2/>
</DataTemplate>
</Window.Resources>
<ContentControl Content="Binding CurrentViewModel"/>
有了这个,你需要做的就是有一些逻辑来改变 MainWindow
ViewModel 上的 ViewModel 并且 View 将更新以显示该 ViewModel 的正确 View。
编辑:需要注意的一点是,人们使用许多不同的方式来实现你想要的东西,它们都没有真正的正确或错误,但它们都适合不同的人的需求和编码风格。
【讨论】:
我是否创建一个包含 ViewModelBase 部分的新类?不能完全弄清楚那部分..我对此很陌生。 你会的,本质上,使用MVVM
你最终会得到很多ViewModels
这些相当于后面的代码但没有直接关系,即直接访问控件, View
这种分离水平很好。通常ViewModels
会使用类似的代码位,最值得注意的是INotifyPropertyChanged
的实现。因此,我们可以将该代码移动到一个名为 ViewModelBase
的类中,并让我们所有其他的 ViewModels
继承它并使用该功能。这种多态性意味着每个 ViewModel 都有自己的类型和 ViewModel 基础类型。
这意味着我们可以在 Windows
ViewModel
上拥有类型为ViewModelBase
的属性并将其切换到任何 ViewModel,因为它们在技术上属于该类型。
我无法理解它。我已经尝试使用你描述的方式,但我无法让它工作......我认为我也没有完全理解你在说什么。
我已经用一张图片更新了我的答案,但我不确定它是否会让它变得更加压倒性。【参考方案2】:
不久前我已经回答了一个类似的问题。
See this post
您可以在您的窗口中创建一个ContentControl
,并在用户点击或其他地方切换绑定UserControl
【讨论】:
我已将主窗口 xaml 和 xaml.cs 更新为您在另一篇文章中提到的 (contentcontrol x:name="contentControl" & this.contentControl.content = "userControl.content") .虽然如果我现在想在完成第一个 userControl 后更改为另一个 usercontrol,我该如何继续? @user8478480 当然是因为我们不喜欢 *** 上的仅链接答案。这应该是一条评论,如果 OP 认为另一个问题与他们的相似,则该问题应作为重复关闭。它当然不值得赞成,您的赞成特权并不意味着补偿您认为不公平的反对票。请仅对好的帖子进行投票。 @Clemens 我明白你在说什么,也许他们没有完全正确地回答这个问题,评论会更好。但归根结底,他们已经继续帮助 OP,不应该因此而被否决。归根结底,他的答案没有错,因此将其向下推也无济于事,现在我们只有 2 个答案为 0。 @user8478480 没有错 并不完全正确,因为它仍然是仅链接的答案。我们只是不想拥有那个。参见例如在这里:meta.***.com/q/265552/1136211。这里当然有第二句话,但没有上下文就不是很有帮助。 @Clemens 我同意它不应该发布,我们不想看到它。就像一个注释,对于一个在 SO, OP 上不问太多问题的用户。有一个反对票的答案可能意味着对 OP “错误”,这也不是很好/有帮助以上是关于如何在一个 xaml 页面中使用多个用户控件?的主要内容,如果未能解决你的问题,请参考以下文章