【问题标题】:Conditional Resources Creation WPF XAML Design / Run time条件资源创建 WPF XAML 设计/运行时
【发布时间】:2015-07-07 21:27:43
【问题描述】:

WPF Cascading Binding 的第一个问题之后,

我注意到我在 MainWindowUserControls 中定义了比预期更多的资源

这在 Snoop

中很常见

  • MainWindow XAML 有一个 MainWindow ViewModel 的“实例”,它用 greenblue 绘制 2 个用户控件

  • 另外还有 2 个用户控件视图模型实例用于 2 个用户控件中的每一个,它们会将内圈绘制为 红色

  1. 我在 Usercontrol 中的第一个意图是能够“live”看到我的控件的外观(我将它涂成红色以区分这个“模型”和主窗口中的绿色和蓝色圆圈)
  2. 我的资源创建起来非常便宜,所以不管我的应用程序中是否还有 2 个额外的资源,但我预计我的资源会更昂贵。 .

最后我的问题是:

如何有条件地让资源在“低级”控件中创建(以便我可以在控件视图中预览)在运行完整应用程序时阻止此创建(或主窗口的视图),因为我将绑定到这个上层的资源。

非常感谢。

最好的问候。

NGI

【问题讨论】:

  • 设计时一个项目,运行时一个项目?
  • @Maximus:只有在设计时,在设计此 UserControl 的外观和感觉时才需要 UserControl 资源(圆圈为红色)。在 MainWindow 的设计期间或应用程序运行期间,MainWindow 资源会强加其数据(绿色和蓝色 2 个圆圈),从而浪费 UserControl 资源
  • @Maximus:嗨,我发现我认为这是一种更简单的方法来解决我在运行完整应用程序时在子控件中浪费视图模型资源的问题。告诉我你对解决方案的看法。

标签: c# wpf binding datacontext resourcedictionary


【解决方案1】:

我准备了在设计时和运行时显示一个数据的简化方法。希望您会发现它有用并根据您的情况进行调整。

XAML:

<Window.Resources>
    <DataTemplate x:Key="DesignModeDataTemplate">
        <TextBlock Text="Design mode"/>
    </DataTemplate>
    <DataTemplate x:Key="RunTimeDataTemplate">
        <TextBlock Text="Run Time"/>
    </DataTemplate>
    <local:IsInDesignModeConverter x:Key="IsInDesignModeConverter"/>
</Window.Resources>
<ContentControl>
    <ContentControl.ContentTemplate>
        <MultiBinding Converter="{StaticResource IsInDesignModeConverter}">
            <Binding Source="{StaticResource DesignModeDataTemplate}"/>
            <Binding Source="{StaticResource RunTimeDataTemplate}"/>
        </MultiBinding>
    </ContentControl.ContentTemplate>
</ContentControl>

转换器:

 class IsInDesignModeConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if ((bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue))
            return values[0];
        return values[1];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

因此,它在设计时显示设计模式文本,在运行时显示运行时文本。 在您的情况下,您可以插入已定义的资源,而不是 TextBlock。

【讨论】:

  • @Maximus:非常感谢您的回复。我刚刚编译它并看到了预期的结果。让我有时间彻底了解它并根据我的情况进行调整
【解决方案2】:

我最终会尝试回答我自己的问题

结果在较低级别的 ViewModel 实例中是等待的没有“重复资源” 窥探的结果:

XAML 代码

<UserControl x:Class="BindingMCVE.UserControl1"
         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:BindingMCVE"
         d:DataContext="{d:DesignInstance {x:Type vm_nmspc:my_usercontrol_vm}, IsDesignTimeCreatable=True}"
         mc:Ignorable="d" 
         d:DesignHeight="100" d:DesignWidth="100"
         xmlns:vm_nmspc="clr-namespace:BindingMCVE.ViewModel"               
 >

<UserControl.Resources>
    <!--No resources created in XAML-->
</UserControl.Resources>


        <Grid>
    <StackPanel  Height="100"  Width="100">
        <Ellipse  Fill="{Binding my_color}" Height="50" Width="50" />
    </StackPanel>

</Grid>

注意换行:

d:DataContext="{d:DesignInstance {x:Type vm_nmspc:my_usercontrol_vm}, IsDesignTimeCreatable=True}"

而且绝对没有其他修改!!

诀窍是使用 IDE 来支持您(如果您不知道会导致 XAML 的语法)。

我会试着说明我做了什么。

选择您的对象,然后在格式菜单中选择 Set Design Time DataContext

然后选择你的 DesignInstance(这里是 ViewModel my_usercontrol_vm)并且不要忘记勾选IsDesignTimeCreatable

这在 Ellipse 声明中创建了 magic 行,但我将它移到了 XAML 的顶部。

所以这回答了我的问题。在没有深入了解 WPF/XAML 的情况下,可以“渲染”所有子视图(控件),而不会浪费视图模型资源的额外成本

为了回应 Maximus 在第一个答案中给出的内容,我还发现了另一个帖子(将尝试再次找到它并在下一次编辑中引用它)直接使用函数 DesignerProperties.GetIsInDesignMode( )

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {

        InitializeComponent();

        if (  DesignerProperties.GetIsInDesignMode(this))
        {
            //Do what you want here for design time specific actions
        }
    }
}

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多