首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于FixedPage的WPF动态资源查找行为

基于FixedPage的WPF动态资源查找行为
EN

Stack Overflow用户
提问于 2012-01-02 10:40:53
回答 2查看 4K关注 0票数 1

具有以下非常简单的xaml:

代码语言:javascript
复制
<DocumentViewer Name="dv">
    <FixedDocument Name="fd" Loaded="fd_loaded">
        <FixedDocument.Resources>
            <Style x:Key="TestStyle">
                <Style.Setters>
                    <Setter Property="TextBlock.Foreground" Value="BlueViolet"/>
                </Style.Setters>
            </Style>
            <SolidColorBrush x:Key="foregroundBrush" Color="Orange"/>
        </FixedDocument.Resources>
        <PageContent Name="pc">
            <FixedPage Name="fp" Width="800" Height="600" Name="fp">
                <TextBlock Name="tb" Style="{DynamicResource TestStyle}">
                        Lorem ipsum
                </TextBlock>
                <TextBlock Foreground="{DynamicResource foregroundBrush}" Margin="20">
                        Lorem ipsum
                </TextBlock>
            </FixedPage>
        </PageContent>
    </FixedDocument>
</DocumentViewer>

在这里使用(在更复杂的情况下我实际上需要它)是行不通的。使用静态资源将TextBlocks用所需的颜色着色。将参考资料移到FixedPage级别也有好处。但是我希望在顶级元素上有一个通用资源字典(因为用户可以为颜色、字体等进行运行时更改)。将资源放在应用程序级别也是有效的。但这不是一个有充分理由的选择。

任何人都不知道为什么这不管用。它与TextBlock上的逻辑树有关吗?

MSDN资源概述指出:

查找过程在由设置属性的元素定义的资源字典中检查请求的密钥。

  • 如果元素定义了样式属性,则将检查样式中的资源字典。
  • 如果元素定义了模板属性,则将检查FrameworkTemplate中的资源字典。

然后,查找过程向上遍历逻辑树,直至父元素及其资源字典。这种情况一直持续到到达根元素为止。

我还试着按照上面对MSDN的解释,将画笔和样式放入(虚拟)样式的参考资料中。但这也没用。

真的有这样的感觉,这不可能是那么复杂,但最有可能的是,我监督的东西。任何帮助都是非常感谢的。

编辑

当将TextBlock命名为"tb“,然后使用tb.FindResource("TestStyle")时,会引发异常。这样资源显然就找不到了。如果我检查了LogicalTreeHelper.GetParent(tb)并对父母重复,我得到了预期的结果: TextBlock > FixedPage > PageContent > FixedDocument。

EDIT2

这是完美的。之前投影的XAML有什么不同?

代码语言:javascript
复制
<Window x:Class="WpfDynamicStyles2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <SolidColorBrush x:Key="resBrush" Color="Orange"></SolidColorBrush>
        </Grid.Resources>
            <StackPanel>
            <Button>
                <TextBlock Foreground="{DynamicResource resBrush}">Dummy text...</TextBlock>
            </Button>           
        </StackPanel>
    </Grid>
</Window>

EDIT3

代码语言:javascript
复制
private void fd_Loaded(object sender, RoutedEventArgs e)
{
    Object obj = pc.TryFindResource("foregroundBrush");
    obj = fp.TryFindResource("foregroundBrush");
    obj = tb.TryFindResource("foregroundBrush");
}

放置在文本框前台属性上的动态资源无法解析(实际资源位于FixedDocument.Resources级别)。此外,在代码背后使用TryFindResource可以从pc (PageContent)中工作,但是使用fp (FixedPage)和tb (TextBlock),它无法解析资源(obj为null)。在XAML标记中使用静态资源时,一切正常。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-16 10:04:04

顺便说一句:这篇文章的原因有一些更复杂的背景。我非常想使用单一的资源字典,在运行时(由最终用户)动态地更改颜色、字体、字体大小等。我正在写一份纳税申请表。屏幕上显示的供用户输入的纳税表格在应用程序级别上解析了他们的资源。到目前一切尚好。

但同时,我想向用户提供纳税表单的打印预览,其中使用相同的资源集(作为对象类型,而不是对象实例)来定义用于打印的配色方案、字体、字体大小等。它可能与屏幕上用户输入所用的样式不同。这就是为什么我希望将资源字典“附加”到(例如) FixedDocument级别,以便文档中的所有页面都引用它。当更改颜色、字体等时,所有具有共同元素的页面(TextBlocks、TextEditors等)会对变化做出反应。

然后我成为了stuck...as在这篇文章中描述的。

现在,我有了一个很好的解决方案,方法是创建资源管理器的特定实例,将其存储为私有变量,并将其附加到固定文档中的每个单独页面。它起作用了,这已经让我高兴了。但是我的程序员的心仍然有点心痛,因为我更喜欢使用资源字典的单个实例,并将它放在某个顶级控件上,以便它中的所有控件都可以使用它。

作为一名程序员,我们也必须接受变通办法;)如果您有任何进一步的建议,我愿意接受它们。谢谢你的支持。

格雷茨,乔普。

另见:MSDN论坛关于这个问题的文章

票数 0
EN

Stack Overflow用户

发布于 2012-01-02 11:38:57

好的,走风格的道路是一个好的设计,但没有必要。为了使基于动态颜色的同名(键控)笔刷,我们可以使用动态颜色字典(而不是笔刷字典)。

解决办法如下..。

  1. 创建单个刷子资源字典。
  2. 使用DynamicResource属性引用画笔中的颜色。
  3. 创建具有相同键的颜色资源的多个资源字典。
  4. 根据用户需求,明确并添加到Application.Current.resources.MergedDictionaries中。

示例

  1. 使用下面的XAML.窗口创建一个WPF项目. <>String>Orange Red Blue

如果您观察到窗口不需要使用,任何都是动态的。所有的推荐人都可以保持静止。所以LabelColorBrush可以在字典Window11Resources.xaml中找到。

  1. Window11Resources.xaml字典中添加一个动态颜色刷。
  2. 在您的项目中的某个文件夹中添加以下3种颜色刷字典.

注意,保持不变,即DynamicColor

  1. 现在在App.Resources中清除并重新创建颜色字典。我已经在Window.xaml.cs后面的代码中这样做了 私有ComboBox_SelectionChanged(对象发送方,SelectionChangedEventArgs e) {SelectionChangedEventArgsApplication.Current.Resources.MergedDictionaries.Add(新ResourceDictionary() { Source =新Uri("Resources\“+((ComboBox)发件人).SelectedItem.ToString()+ "ColorResource.xaml",UriKind.RelativeOrAbsolute) };}

现在,当您从下拉列表中选择颜色时,静态资源刷上的动态颜色会发生变化。请注意,不涉及样式

我希望这能回答你的要求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8699865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档