gpt4 book ai didi

wpf - 制作(创建)可重用的动态 View

转载 作者:行者123 更新时间:2023-12-04 04:25:44 25 4
gpt4 key购买 nike

Out 团队想要创建可重用、可样式化的 View 。例如,我们希望在不同的应用程序中重用 CommonPromptView (我们自己的可定制对话框,我们可以在其中隐藏“取消”按钮、设置标题、显示特定图标等)。

该 View 的表面上有几个元素:TextBlocks、Buttons。我们想让它们样式化。

那么,解决此任务的最佳方法是什么?

  • View 可以是 Window 类型。
  • View 可以是 UserControl 类型。

  • 在第一种情况下,可以通过两种方式支持样式:
  • 元素的样式引用了 DynamicResources。
  • 样式被传递给 View 的构造函数。

  • 两者都不干净(在我看来)。

    但是,如果 View 是 UserControl,那么每次创建新应用程序的人都必须创建一个新窗口来包含 UserControl 并将其绑定(bind)设置为正确的 DP(样式类型)。此外,如果一个 UserControl 有它自己的非常方便的 API(最常用操作的静态方法),对于包含 UserControl 的窗口的用户来说,这些 API 将丢失。

    Update
    CommonPromptView 的示例实现为用户控件。
    Code-behind
     public sealed partial class CommonPromptView {
    private const int CloseViewTimeIntervalInMilliseconds = 120000;
    private DispatcherTimer timer;

    public static readonly DependencyProperty CommonPromptBorderStyleProperty = DependencyProperty.Register(
    "CommonPromptBorderStyle", typeof (Style), typeof (CommonPromptView), new PropertyMetadata(default(Style)));

    public Style CommonPromptBorderStyle {
    get { return (Style) GetValue(CommonPromptBorderStyleProperty); }
    set { SetValue(CommonPromptBorderStyleProperty, value); }
    }

    public static readonly DependencyProperty CommonPromptHeaderStyleProperty = DependencyProperty.Register(
    "CommonPromptHeaderStyle", typeof (Style), typeof (CommonPromptView), new PropertyMetadata(default(Style)));

    public Style CommonPromptHeaderStyle {
    get { return (Style) GetValue(CommonPromptHeaderStyleProperty); }
    set { SetValue(CommonPromptHeaderStyleProperty, value); }
    }

    public static readonly DependencyProperty CommonPromptMessageStyleProperty = DependencyProperty.Register(
    "CommonPromptMessageStyle", typeof (Style), typeof (CommonPromptView), new PropertyMetadata(default(Style)));

    public Style CommonPromptMessageStyle {
    get { return (Style) GetValue(CommonPromptMessageStyleProperty); }
    set { SetValue(CommonPromptMessageStyleProperty, value); }
    }

    public static readonly DependencyProperty CommonPromptSpitterStyleProperty = DependencyProperty.Register(
    "CommonPromptSpitterStyle", typeof (Style), typeof (CommonPromptView), new PropertyMetadata(default(Style)));

    public Style CommonPromptSpitterStyle {
    get { return (Style) GetValue(CommonPromptSpitterStyleProperty); }
    set { SetValue(CommonPromptSpitterStyleProperty, value); }
    }

    public static readonly DependencyProperty CommonPromptButtonStyleProperty = DependencyProperty.Register(
    "CommonPromptButtonStyle", typeof (Style), typeof (CommonPromptView), new PropertyMetadata(default(Style)));

    public Style CommonPromptButtonStyle {
    get { return (Style) GetValue(CommonPromptButtonStyleProperty); }
    set { SetValue(CommonPromptButtonStyleProperty, value); }
    }

    [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public CommonPromptView(object header = null, string message = "Вы действительно хотите продолжить?",
    Visibility headerVisibility = Visibility.Collapsed,
    MessageBoxIconWPF iconType = MessageBoxIconWPF.Question,
    object affirmButtonContent = null, object cancelButtonContent = null,
    Visibility cancelButtonVisibility = Visibility.Visible, Visibility affirmButtonVisibility = Visibility.Visible) {
    InitializeComponent();
    Header.Content = header ?? string.Empty;
    if (header == null)
    HeaderSplitter.Visibility = Visibility.Collapsed;
    Message.Content = message;

    Ok.Content = affirmButtonContent ?? "ОК";
    Cancel.Content = cancelButtonContent ?? "Отмена";

    Cancel.Visibility = cancelButtonVisibility;
    Header.Visibility = headerVisibility;
    Ok.Visibility = affirmButtonVisibility;

    BitmapImage icon = new BitmapImage();
    icon.BeginInit();
    icon.UriSource = new Uri(GetIconPath(iconType));
    //new Uri("pack://application:,,,/ApplicationName;component/Resources/logo.png");
    icon.EndInit();

    Icon.Source = icon;

    SetTimer();
    }

    private static string GetIconPath(MessageBoxIconWPF icon) {
    const string uri = "pack://application:,,,/Microtech.WPF.Common;component/";
    string iconName;
    switch (icon) {
    case MessageBoxIconWPF.Error:
    iconName = "CustomDialogStop";
    break;
    case MessageBoxIconWPF.Information:
    iconName = "CustomDialogInformation";
    break;
    case MessageBoxIconWPF.Question:
    iconName = "CustomDialogQuestion";
    break;
    case MessageBoxIconWPF.Warning:
    iconName = "CustomDialogWarning";
    break;
    default:
    throw new ArgumentException("There were no such an image");
    }
    return uri + string.Format("Images/{0}.{1}", iconName, "png");
    }

    public CommonPromptView(string content, Visibility cancelButtonVisibility = Visibility.Visible)
    : this(message: content, cancelButtonVisibility: cancelButtonVisibility) {
    }

    private void SetTimer() {
    TimeSpan timerInterval = TimeSpan.FromMilliseconds(CloseViewTimeIntervalInMilliseconds);
    timer = new DispatcherTimer(timerInterval, DispatcherPriority.ApplicationIdle,
    (obj, e) => Cancel_Click(null, null),
    Dispatcher.CurrentDispatcher);
    timer.Start();
    }

    public CommonPromptView() {
    InitializeComponent();
    }

    public static bool PromptOnUserAgreement(string header, string message, string okText = "Да",
    string cancelText = "Нет") {
    return new CommonPromptView(header,
    message, Visibility.Visible, MessageBoxIconWPF.Information, okText, cancelText).ShowDialog()
    .GetValueOrDefault();
    }

    public static void PromptOnWarning(string header, string message) {
    new CommonPromptView(header, message, headerVisibility: Visibility.Visible, iconType: MessageBoxIconWPF.Warning,
    cancelButtonVisibility: Visibility.Collapsed).ShowDialog();
    }

    public static void PromptOnError(string header, string message) {
    new CommonPromptView(header, message, headerVisibility: Visibility.Visible, iconType: MessageBoxIconWPF.Error,
    cancelButtonVisibility: Visibility.Collapsed).ShowDialog();
    }

    public static void PromptOnSuccess(string header, string message) {
    new CommonPromptView(header, message, headerVisibility: Visibility.Visible,
    iconType: MessageBoxIconWPF.Information,
    cancelButtonVisibility: Visibility.Collapsed).ShowDialog();
    }

    private void Ok_Click(object sender, RoutedEventArgs e) {
    StopTimer();
    TryCloseTheWindow(true);
    }

    private void Cancel_Click(object sender, RoutedEventArgs e) {
    StopTimer();
    TryCloseTheWindow(false);
    }

    private void TryCloseTheWindow(bool dialogResult) {
    Window parentwin = GetWindow(this);
    if (parentwin != null) {
    try {
    parentwin.DialogResult = dialogResult;
    } catch (InvalidOperationException) {

    }
    parentwin.Close();
    }
    }

    private void StopTimer() {
    if (timer != null) {
    timer.Stop();
    timer = null;
    }
    }
    }
    XAML
    <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Microtech.WPF.Common.CommonPromptView"
    Background="Transparent"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <UserControl.Resources>
    <Style x:Key="DefaultViewStyle" TargetType="Window">
    <Setter Property="ResizeMode" Value="NoResize" />
    <Setter Property="ShowInTaskbar" Value="False" />
    <Setter Property="WindowStyle" Value="None" />
    <Setter Property="WindowState" Value="Normal" />
    <Setter Property="SizeToContent" Value="WidthAndHeight" />
    <Setter Property="Topmost" Value="True" />
    <Setter Property="Cursor" Value="Arrow" />
    </Style>

    <Style x:Key="DefaultHeaderStyle" TargetType="Label">
    <Setter Property="Margin" Value="10,5,5,5"/>
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="FontSize" Value="20" />
    <Setter Property="FontWeight" Value="Bold" />
    </Style>

    <Style x:Key="DefaultBorderStyle" TargetType="Border">
    <Setter Property="Background" Value="#ADAAAD"/>
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="Padding" Value="10" />
    <Setter Property="BorderThickness" Value="3"/>
    <Setter Property="CornerRadius" Value="10"/>
    </Style>

    <Style x:Key="DefaultMessageStyle" TargetType="Label">
    <Setter Property="Margin" Value="10"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="FontFamily" Value="Verdana"/>
    <Setter Property="FontWeight" Value="Normal"/>
    </Style>

    <Style x:Key="DefaultSplitterStyle" TargetType="GridSplitter">
    <Setter Property="HorizontalAlignment" Value="Stretch" />
    <Setter Property="VerticalAlignment" Value="Bottom" />
    <Setter Property="BorderThickness" Value="0.65" />
    <Setter Property="BorderBrush" Value="Black" />
    <Setter Property="IsEnabled" Value="False" />
    </Style>

    <Style x:Key="FStandartButton" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="{x:Null}" />
    <Setter Property="BorderBrush" Value="#00000000" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="Height" Value="Auto" />
    <Setter Property="MinHeight" Value="55" />
    <Setter Property="Width" Value="420" />
    <Setter Property="Margin" Value="5" />
    <Setter Property="Padding" Value="10" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />

    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="Button">
    <Border x:Name="border" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="4,4,4,4">
    <Border.Background>
    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
    <GradientStop Offset="0" Color="#8C8A8C" />
    <GradientStop Offset="1" Color="#636163" />
    </LinearGradientBrush>
    </Border.Background>
    <ContentPresenter Name="ContentContainer"
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
    RecognizesAccessKey="True"
    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
    </Border>
    <ControlTemplate.Triggers>
    <Trigger Property="IsPressed" Value="True">
    <Setter TargetName="border" Property="Background" Value="#CC000000" />
    </Trigger>
    <Trigger Property="IsEnabled" Value="False">
    <Setter Property="Foreground" Value="Gray" />
    </Trigger>

    </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>

    <Style x:Key="DefaultButtonStyle" TargetType="Button" BasedOn="{StaticResource FStandartButton}">
    <Setter Property="FontFamily" Value="Verdana"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Margin" Value="6"/>
    </Style>
    </UserControl.Resources>

    <Border Style="{Binding CommonPromptBorderStyle, TargetNullValue={StaticResource DefaultBorderStyle}}">
    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Label x:Name="Header"
    Style="{Binding CommonPromptHeaderStyle, TargetNullValue={StaticResource DefaultHeaderStyle}}" />
    <GridSplitter x:Name="HeaderSplitter" Grid.Row="0"
    Style="{Binding CommonPromptSpitterStyle, TargetNullValue={StaticResource DefaultSplitterStyle}}"
    />

    <StackPanel Grid.Row="1" Margin="5,10,5,0" Orientation="Horizontal">
    <Image x:Name="Icon" Width="32" Height="32" Margin="5"
    HorizontalAlignment="Left"
    VerticalAlignment="Center" />
    <Label x:Name="Message"
    Style="{Binding CommonPromptMessageStyle,
    TargetNullValue={StaticResource DefaultMessageStyle}}" />
    </StackPanel>

    <StackPanel Grid.Row="2" HorizontalAlignment="Center" Orientation="Horizontal">
    <Button x:Name="Ok"
    Style="{Binding CommonPromptButtonStyle, TargetNullValue={StaticResource DefaultButtonStyle}}"
    Click="Ok_Click" />
    <Button x:Name="Cancel"
    Style="{Binding CommonPromptButtonStyle, TargetNullValue={StaticResource DefaultButtonStyle}}"
    IsDefault="True" Click="Cancel_Click" />
    </StackPanel>
    </Grid>
    </Border>

    最佳答案

    我认为在您的情况下,您需要朝 DataTemplate 的方向看, 制作动态内容。我举了几个例子来说明这一点。这个例子的一般含义:

    Given two buttons, one for the user and one for the administrator. If you choose the User, the content is displayed to the user, if the Admin, then for administrator.



    显然,这不是最现实的例子,但它只是展示动态选择内容的一种方式。对于您,您将确定替换内容的条件。

    Example A

    这个例子演示了动态替换 DataTemplates ,取决于输入值​​。如果我们从样式模式的角度来考虑,它与抽象工厂非常相似,其中没有类 - DataTemplate , 工厂方法是动态的 DataTemplate选择器。示例完全适合 MVVM图案。下面是一个例子:
    MainWindow.xaml
    <Grid>
    <ContentControl Name="MainView"
    ContentTemplate="{StaticResource MainView}">

    <ViewModels:MainViewModel />
    </ContentControl>
    </Grid>
    MainView.xaml
    这是一个 DataTemplateResourceDictionary .有两个模板:UserTemplate 和 AdminTemplate。一份给用户,一份给管理员。 ContentControl 的风格定义了 ContentTemplateSelector,以及将由条件安装的模板集合。在属性 Content为 DynamicContentControl 设置内容字符串,可以是: UserAdmin .
    <DataTemplateSelectors:DynamicTemplateSelector x:Key="MyTemplateSelector" />

    <DataTemplate x:Key="UserTemplate">
    <StackPanel>
    <TextBlock Text="Content for user"
    FontSize="20"
    HorizontalAlignment="Center"
    VerticalAlignment="Center" />

    <Button Content="Yes" />
    <Button Content="No" />
    </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="AdminTemplate">
    <StackPanel>
    <TextBlock Text="Content for admin"
    FontSize="20"
    HorizontalAlignment="Center"
    VerticalAlignment="Center" />

    <TextBox Text="Whom banned?" />
    <Button Content="Ban" />
    <Button Content="AntiBan" />
    </StackPanel>
    </DataTemplate>

    <Style x:Key="DynamicContentStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="ContentTemplateSelector" Value="{StaticResource MyTemplateSelector}" />
    <Setter Property="Width" Value="200" />
    <Setter Property="Height" Value="200" />

    <Setter Property="DataTemplateSelectors:DynamicTemplateSelector.Templates">
    <Setter.Value>
    <DataTemplateSelectors:TemplateCollection>
    <DataTemplateSelectors:Template Value="User"
    DataTemplate="{StaticResource UserTemplate}" />

    <DataTemplateSelectors:Template Value="Admin"
    DataTemplate="{StaticResource AdminTemplate}" />
    </DataTemplateSelectors:TemplateCollection>
    </Setter.Value>
    </Setter>
    </Style>

    <DataTemplate x:Key="MainView" DataType="{x:Type ViewModels:MainViewModel}">
    <Grid>
    <Button Name="UserButton"
    Content="Are you user?"
    Width="100"
    Height="30"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    Command="{Binding UserButtonCommand}" />

    <Button Name="AdminButton"
    Content="Are you admin?"
    Width="100"
    Height="30"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    Command="{Binding AdminButtonCommand}" />

    <ContentControl Name="DynamicContent"
    Style="{StaticResource DynamicContentStyle}"
    Content="{Binding Path=MainModel.ContentType,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}" />
    </Grid>
    </DataTemplate>
    MainViewModel.cs
    这里在命令中设置内容类型。
    public class MainViewModel
    {
    #region MainModel

    private MainModel _mainModel = null;

    public MainModel MainModel
    {
    get
    {
    return _mainModel;
    }

    set
    {
    _mainModel = value;
    }
    }

    #endregion

    #region UserButton Command

    private ICommand _userButtonCommand = null;

    public ICommand UserButtonCommand
    {
    get
    {
    if (_userButtonCommand == null)
    {
    _userButtonCommand = new RelayCommand(param => this.UserButton(), null);
    }

    return _userButtonCommand;
    }
    }

    private void UserButton()
    {
    MainModel.ContentType = "User";
    }

    #endregion

    #region AdminButton Command

    private ICommand _adminButtonCommand = null;

    public ICommand AdminButtonCommand
    {
    get
    {
    if (_adminButtonCommand == null)
    {
    _adminButtonCommand = new RelayCommand(param => this.AdminButton(), null);
    }

    return _adminButtonCommand;
    }
    }

    private void AdminButton()
    {
    MainModel.ContentType = "Admin";
    }

    #endregion

    public MainViewModel()
    {
    MainModel = new MainModel();
    }
    }
    MainModel.cs
    public class MainModel : NotificationObject
    {
    private string _contentType = "";

    public string ContentType
    {
    get
    {
    return _contentType;
    }

    set
    {
    _contentType = value;
    NotifyPropertyChanged("ContentType");
    }
    }
    }
    DynamicTemplateSelector
    从 CodeProject 中提取并且很少修改:
    public class DynamicTemplateSelector : DataTemplateSelector
    {
    #region Templates Dependency Property

    public static readonly DependencyProperty TemplatesProperty =
    DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DataTemplateSelector),
    new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits));

    public static TemplateCollection GetTemplates(UIElement element)
    {
    return (TemplateCollection)element.GetValue(TemplatesProperty);
    }

    public static void SetTemplates(UIElement element, TemplateCollection collection)
    {
    element.SetValue(TemplatesProperty, collection);
    }

    #endregion

    #region SelectTemplate

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
    string myStringItem = (string)item;

    if (!(container is UIElement))
    {
    return base.SelectTemplate(item, container);
    }

    TemplateCollection templates = GetTemplates(container as UIElement);

    if (templates == null || templates.Count == 0)
    {
    base.SelectTemplate(item, container);
    }

    foreach (var template in templates)
    {
    if (myStringItem.Equals(template.Value.ToString()))
    {
    return template.DataTemplate;
    }
    }

    return base.SelectTemplate(item, container);
    }

    #endregion
    }

    #region TemplateCollection

    public class TemplateCollection : List<Template>
    {

    }

    #endregion

    #region Template Dependency Object

    public class Template : DependencyObject
    {
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(Template));

    public static readonly DependencyProperty DataTemplateProperty =
    DependencyProperty.Register("DataTemplate", typeof(DataTemplate), typeof(Template));

    public string Value
    { get { return (string)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } }

    public DataTemplate DataTemplate
    { get { return (DataTemplate)GetValue(DataTemplateProperty); } set { SetValue(DataTemplateProperty, value); } }
    }

    #endregion
    Result for User
    Result for user
    Result for Admin
    Result for admin
    Notes about this way
    好处:
  • 完全独立于不同的 View

  • 缺点:
  • 需要为每个条件创建一个单独的数据模板(View),在某些情况下是 ViewModel。

  • 结论:

    这种方法适用于完全不同的 View ,如果表示差别不大,你看第二个例子。

    Example B

    此示例使用一个 DataTemplate ,数据取自模型,默认情况下,所有控件都隐藏( Visibility.Collapsed), View中的所有 Action 通过 DataTriggers 执行.示例完全适合 MVVM图案。
    MainWindow.xaml
    <Grid>
    <ContentControl Name="MainView"
    ContentTemplate="{StaticResource MainView}">

    <ViewModels:MainViewModel />
    </ContentControl>
    </Grid>
    MainView.xaml
    <DataTemplate x:Key="MainView" DataType="{x:Type ViewModels:MainViewModel}">
    <Grid>
    <Button Name="UserButton"
    Content="Are you user?"
    Width="100"
    Height="30"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    Command="{Binding UserButtonCommand}" />

    <Button Name="AdminButton"
    Content="Are you admin?"
    Width="100"
    Height="30"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    Command="{Binding AdminButtonCommand}" />

    <StackPanel Name="MainViewPanel"
    Tag="{Binding Path=MainModel.ContentType,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}">

    <TextBlock Name="TitleTextBlock"
    Text="{Binding Path=MainModel.TitleText,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}"
    FontSize="20"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Visibility="Collapsed" />

    <TextBox Name="BannedTextBlock"
    Text="{Binding Path=MainModel.BannedName,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}"
    Visibility="Collapsed" />

    <Button Name="YesButton"
    Content="{Binding Path=MainModel.ContentYesButton,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}"
    Visibility="Collapsed" />

    <Button Name="NoButton"
    Content="{Binding Path=MainModel.ContentNoButton,
    Mode=TwoWay,
    UpdateSourceTrigger=PropertyChanged}"
    Visibility="Collapsed" />
    </StackPanel>
    </Grid>

    <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding ElementName=MainViewPanel, Path=Tag}" Value="User">
    <Setter TargetName="TitleTextBlock" Property="Visibility" Value="Visible" />
    <Setter TargetName="YesButton" Property="Visibility" Value="Visible" />
    </DataTrigger>

    <DataTrigger Binding="{Binding ElementName=MainViewPanel, Path=Tag}" Value="Admin">
    <Setter TargetName="TitleTextBlock" Property="Visibility" Value="Visible" />
    <Setter TargetName="BannedTextBlock" Property="Visibility" Value="Visible" />
    <Setter TargetName="YesButton" Property="Visibility" Value="Visible" />
    <Setter TargetName="NoButton" Property="Visibility" Value="Visible" />
    </DataTrigger>
    </DataTemplate.Triggers>
    </DataTemplate>
    MainViewModel.cs
    public class MainViewModel
    {
    #region MainModel

    private MainModel _mainModel = null;

    public MainModel MainModel
    {
    get
    {
    return _mainModel;
    }

    set
    {
    _mainModel = value;
    }
    }

    #endregion

    #region UserButton Command

    private ICommand _userButtonCommand = null;

    public ICommand UserButtonCommand
    {
    get
    {
    if (_userButtonCommand == null)
    {
    _userButtonCommand = new RelayCommand(param => this.UserButton(), null);
    }

    return _userButtonCommand;
    }
    }

    private void UserButton()
    {
    MainModel.ContentType = "User";
    MainModel.TitleText = "Hello User!";
    MainModel.ContentYesButton = "Yes";
    MainModel.ContentNoButton = "No";
    }

    #endregion

    #region AdminButton Command

    private ICommand _adminButtonCommand = null;

    public ICommand AdminButtonCommand
    {
    get
    {
    if (_adminButtonCommand == null)
    {
    _adminButtonCommand = new RelayCommand(param => this.AdminButton(), null);
    }

    return _adminButtonCommand;
    }
    }

    private void AdminButton()
    {
    MainModel.ContentType = "Admin";
    MainModel.TitleText = "Hello Admin!";
    MainModel.BannedName = "John Doe";
    MainModel.ContentYesButton = "Ban";
    MainModel.ContentNoButton = "AntiBan";
    }

    #endregion

    public MainViewModel()
    {
    MainModel = new MainModel();
    }
    }
    MainModel.cs
    public class MainModel : NotificationObject
    {
    #region ContentType

    private string _contentType = "";

    public string ContentType
    {
    get
    {
    return _contentType;
    }

    set
    {
    _contentType = value;
    NotifyPropertyChanged("ContentType");
    }
    }

    #endregion

    #region TitleText

    private string _titleText = "";

    public string TitleText
    {
    get
    {
    return _titleText;
    }

    set
    {
    _titleText = value;
    NotifyPropertyChanged("TitleText");
    }
    }

    #endregion

    #region BannedName

    private string _bannedName = "";

    public string BannedName
    {
    get
    {
    return _bannedName;
    }

    set
    {
    _bannedName = value;
    NotifyPropertyChanged("BannedName");
    }
    }

    #endregion

    #region ContentYesButton

    private string _contentYesButton = "";

    public string ContentYesButton
    {
    get
    {
    return _contentYesButton;
    }

    set
    {
    _contentYesButton = value;
    NotifyPropertyChanged("ContentYesButton");
    }
    }

    #endregion

    #region ContentNoButton

    private string _contentNoButton = "";

    public string ContentNoButton
    {
    get
    {
    return _contentNoButton;
    }

    set
    {
    _contentNoButton = value;
    NotifyPropertyChanged("ContentNoButton");
    }
    }

    #endregion
    }
    Result for User
    Result for user
    Result for Admin
    Result for admin
    Notes about this way
    好处:
  • 只有一个数据模板

  • 缺点:
  • 如果表示彼此非常不同,则在 View 中需要操作大量的控件和数据。

  • 结论:

    此方法适用于 Views , 彼此差别不大,不同值的个数也不会太大。

    Both examples are available at this link.

    关于wpf - 制作(创建)可重用的动态 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20839096/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com