Conditional Resources Creation WPF XAML Design / Run time

前端 未结 2 1523
长发绾君心
长发绾君心 2021-01-24 02:06

Following a first question on WPF Cascading Binding,

I remarked that I had more Resources than desired defined in both the MainWindow

相关标签:
2条回答
  • 2021-01-24 02:47

    I prepared simplified way out displaying one data during design time and latter during run time. Hopefully you will find it useful and adjust to your case.

    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>
    

    Converter:

     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();
        }
    }
    

    As a result it display Design mode text during design time and Run time when running. In your case instead of TextBlock you can insert already defined resources.

    0 讨论(0)
  • 2021-01-24 02:52

    I will finally try to answer my own question

    Result is as awaited no "duplicate resources" in the lower level ViewModel instances The result in snoop: Snoop view. Only the mainwindow viewmodel instance

    The XAML code

    <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>
    

    Note the new line:

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

    And there is absolutely no other modifications !!

    The trick is to use the IDE to support you ( if you are unaware of the syntax that will result in the XAML ).

    I will try to illustrate what I did.

    Choose your object, and in the format menu choose Set Design Time DataContext

    Set Design Time DataContext

    Then choose your DesignInstance ( here the ViewModel my_usercontrol_vm) and do not forget to tick IsDesignTimeCreatable

    enter image description here

    This created the magic line in the Ellipse declaration but I moved it on the top of the XAML.

    So this answered my question. It is possible with no deep knowledge on WPF/XAML to make all your subviews (controls) "rendered" without the additional cost of wasted resources of viewmodels

    To give echo to what Maximus gave in the first answer, I found also another post (will try to find it again and quote it in a next edit) using directly the function DesignerProperties.GetIsInDesignMode( )

    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
    
            InitializeComponent();
    
            if (  DesignerProperties.GetIsInDesignMode(this))
            {
                //Do what you want here for design time specific actions
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题