条件资源创建 WPF XAML 设计/运行 时间

Conditional Resources Creation WPF XAML Design / Run time

在第一个问题 之后,

我说我在 MainWindow用户控件:

这在 Snoop

中很常见

  1. 我在 Usercontrol 中的第一个意图是能够看到“live”我的控件的外观(我画了它红色以将此 "model" 与 Main Window)
  2. 中的绿色和蓝色圆圈区分开来
  3. 我的 资源 的创建成本非常低,所以无论我的应用程序中是否还有 2 个额外的资源,但我会预计我的资源将在什么时候出现更贵...

最后我的问题是:

我怎样才能有条件地让资源在 "low level" 控件中创建(以便我可以在控件的视图中进行预览)但是 阻止此创建时运行 完整的应用程序(或 Main Window 的视图),因为我将绑定到此上层的资源。

非常感谢。

此致。

NGI

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

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。

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

结果如期而至在较低级别的 ViewModel 实例中没有“重复资源” snoop 中的结果:

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 中使用的语法)。

我将尝试说明我所做的事情。

选择您的对象,然后在格式菜单中选择设置设计时数据上下文

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

这在 Ellipse 声明中创建了 magic 行,但我将其移到了 XAML.

的顶部

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

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

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

        InitializeComponent();

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