【问题标题】:How to create a dynamic interface in XAML如何在 XAML 中创建动态接口
【发布时间】:2014-04-09 00:09:22
【问题描述】:

如果有人知道使用数据相关 (DataContext="{Binding User}") 或静态数据 (DataContext="{Binding User, Source={StaticResource Locator}}") 创建动态 xaml 的解决方案?

这样的解决方案可以保存在控件隐藏和附加字段(Visibility="{Binding IsAnonim, Converter={StaticResource VisibilityConverter}}")上。而且 XAML 必须只满足这种情况下需要的内容,并且不会充满不必要的控件。

可以在渲染时刻执行的代码(“if (IsUser) { }”)。

下面的例子:

    <UserControl
        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"
        d:DesignHeight="300" d:DesignWidth="400">
        <Grid x:Name="LayoutRoot" DataContext="{Binding User}">
            <StackPanel>
<? if (IsUser) { ?>
   <TextBox Text="{Binding UserName, Mode=TwoWay}" />
   <PasswordBox Text="{Binding UserPass, Mode=TwoWay}" />
<? } else if (IsAnonim) { ?>
   <TextBox Text="{Binding AnonimName, Mode=TwoWay}" />
<? } ?>
                <TextBox Text="{Binding MsgText, Mode=TwoWay}" />
                <Button Content="Button" Command="{Binding PostCommand}" />        
            </StackPanel>
        </Grid> </UserControl>

附:其他解决方案是可能的。谢谢。

【问题讨论】:

  • 如果您的User 属性中有不同类型的对象,您可以使用不同的DataTemplate 并适当地设置它们的DataType。否则,在其 ContentTemplateSelector 属性中使用带有适当 DataTemplateSelector 的 ContentControl。您可以查看 MSDN 上的Data Templating Overview 文章。
  • 我得写两个模板。我正在这样做,它很耗时。

标签: wpf silverlight xaml dynamic interface


【解决方案1】:

绑定和可见性很简单

<UserControl
   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"
   d:DesignHeight="300" d:DesignWidth="400">
   <UserControl.Resources>
     <Convertors:BooleanToInvisibiltyConverterx:Key="booleanToInvisibiltyConverter"/>
     <BooleanToVisibiltyConverterx:Key="booleanToVisibiltyConverter"/>
   </UserControl.Resources>

   <Grid x:Name="LayoutRoot" DataContext="{Binding User}">
     <StackPanel>
       <StackPanel Visibility="{Binding IsUser, Converter={StaticResource booleanToVisibiltyConverter}}">
         <TextBox Text="{Binding UserName, Mode=TwoWay}" />
         <PasswordBox Text="{Binding UserPass, Mode=TwoWay}" />
      </StackPanel>
      <StackPanel Visibility="{Binding IsUser, Converter={StaticResource booleanToInvisibiltyConverter}}">
        <TextBox Text="{Binding AnonimName, Mode=TwoWay}" />
      </StackPanel
      <TextBox Text="{Binding MsgText, Mode=TwoWay}" />
      <Button Content="Button" Command="{Binding PostCommand}" />        
    </StackPanel>
  </Grid>
</UserControl>

您只需要定义资源并创建一个 InvisibiltyConverter

/// <summary>The boolean to invisibility converter.</summary>
public class BooleanToInvisibilityConverter : IValueConverter
{
    /// <summary>The convert.</summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target type.</param>
    /// <param name="parameter">The parameter.</param>
    /// <param name="culture">The culture.</param>
    /// <returns>The <see cref="object"/>.</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null 
            && (bool)value == true)
        {
            return Visibility.Collapsed;
        }

        return Visibility.Visible;
    }

    /// <summary>The convert back.</summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target type.</param>
    /// <param name="parameter">The parameter.</param>
    /// <param name="culture">The culture.</param>
    /// <returns>The <see cref="object"/>.</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

但是随着复杂性的增加,您会发现将所有 UI 保存在单个 xaml 文件中变得不可能。那时,您需要按照 cmets 中的 @Clemens 建议了解数据模板。见Data templating overview

【讨论】:

  • 您没有阅读我的问题。我不想渲染隐藏的控件。
  • LOL,不可见的控件被渲染了?我认为您的意思是您不想在 xaml.xml 中定义控件。无论哪种方式,正如@Clemens 建议的那样使用数据模板
  • 是的,渲染的是不可见的控件,而不是渲染控件的内容。 >> “我认为您的意思是您不想在 xaml 中定义控件。” - 所以,我们可以这样说
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
相关资源
最近更新 更多