【问题标题】:Load ResourceDictionary item dynamically based on property value根据属性值动态加载 ResourceDictionary 项
【发布时间】:2017-08-15 08:34:11
【问题描述】:

是否可以根据我的视图模型中的字符串属性加载我的堆栈面板之一?因此,如果字符串是 MyStackPanel1,那么适当的堆栈面板将被注入到我的主窗口的网格中。

我的资源字典

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel x:Key="MyStackPanel1" Background="{Binding Color}"> 
       // Has some content     
    </StackPanel>

    <StackPanel x:Key="MyStackPanel2" Background="{Binding Color}">   
     // Has some other content
    </StackPanel>
</ResourceDictionary>

我的主窗口:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid>

    </Grid>
</Window>

这里是视图模型的一个想法:

public class ViewModel : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;
  public string StackPanelName { get; set; };
  public string Color { get; set; };

   private void ChangedHandler(string propertyToBeChanged) {

   }
}

【问题讨论】:

  • 而不是将&lt;StackPanel&gt; 存储在 ResourceDictionary 中(警告:它们是共享的)我建议您切换到 DataTemplates 并使用 DataTemplateSelector 根据属性值选择正确的模板(或者不使用 DataTemplateSelector 并设置选择正确的模板通过样式数据触发器)
  • 在此处查看一些示例:stackoverflow.com/questions/20468126/…
  • 你为什么要定义相同的 StackPanels 作为资源开始?此外,视图模型不应具有名为“StackPanelName”的属性。
  • @mm8 很有趣,你能解释一下为什么吗?我认为纯视图数据和状态属于视图模型。

标签: c# wpf xaml resourcedictionary


【解决方案1】:

您可以将ContentControlContentTemplates 一起使用,但要使绑定起作用,您应该设置ContentControlContent 属性:

<Window.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="MyResource1" x:Shared="false">
            <StackPanel>
                <TextBlock Background="{Binding background}">Hello World</TextBlock>
            </StackPanel>
        </DataTemplate>

        <!-- Resource2 and so on -->
    </ResourceDictionary>
</Window.Resources>

<Grid x:Name="Body">
    <!-- "background" is a property of the view model -->
    <ContentControl x:Name="Sample" Content="{Binding}" ContentTemplate="{StaticResource MyResource1}"/>
</Grid>

【讨论】:

    【解决方案2】:

    我想我知道如何解决这个问题。首先我定义一个资源列表:

    我在 XAML 中写:

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="MyResourceDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    
    <Grid x:Name="Body">
        <ContentControl x:Name="Sample" ContentTemplate="{StaticResource MyResource1}"/>
    </Grid>
    

    现在在我的资源字典中:

    <DataTemplate x:Key="MyResource1" x:Shared="false">
        <StackPanel>
            <TextBlock Background="{Binding background}">Hello World</TextBlock>
        </StackPanel>
    </DataTemplate>
    
    // Resource2 and so on
    

    那么在我看来,我可以做到以下几点:

    public void SwapResource(ContentControl contentControl, string resourceName) {
        contentControl.ContentTemplate = (DataTemplate)FindResource(resourceName);
    }
    

    问题是绑定不起作用...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-02
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      相关资源
      最近更新 更多