【问题标题】:How to remove a dictionary resource reference from a TextBlock?如何从 TextBlock 中删除字典资源引用?
【发布时间】:2021-01-06 18:40:37
【问题描述】:

我有这个元素:

<TextBlock Style="{StaticResource textReplyMessageStyle}">
   <Run x:Name="answerMessage" Text="{Binding Message, Mode = OneWay, FallbackValue = ''}" />
</TextBlock>

而且我需要在 answerMessage 中打印 var Message 的内容(感谢绑定)或字典中的元素(感谢以下代码完成的资源引用)。

answerMessage.SetResourceReference(Run.TextProperty, "Answer_Message_Not_Selected");

绑定和字典引用一样可以正常工作,但是在设置资源引用后我找不到让绑定再次工作的方法。

我尝试以编程方式重新进行绑定,但无法正常工作... 我发现的唯一可行的解​​决方法是以编程方式设置 answerMessage 的文本。
如何从 Run 元素中删除资源引用并使绑定再次起作用?

只是为了提供一些上下文,变量 Message 包含一个数字和资源 Answer_Message_Not_Selected 包含文本“未选择”或不同语言的翻译,具体取决于程序上激活的词典。我必须使用动态资源引用,因为程序的语言可以随时更改。

谢谢!

【问题讨论】:

  • 你能显示你的绑定重做代码吗?
  • 当您在 Run 元素上设置资源引用时,您会破坏您在 xaml 中为其设置的绑定。重新绑定听起来是正确的,所以如果它不起作用,您需要查看调试输出以查看是否存在绑定错误。另一个问题是,为什么要更改 run 本身的值,而不是更改它在 ViewModel 中绑定的值?
  • @JasonTyler @o_w 我设法修复它,它确实是绑定。这是我提醒组件的方式错误。 Binding b = new Binding(); b.Path = new PropertyPath("Message"); b.Source = this; BindingOperations.SetBinding(answerMessage, Run.TextProperty, b);
  • @o_w 你的观点非常好。这不是一个干净的解决方案。我没有设置 ResourceReference,而是尝试通过以下方式将 Answer_Message_Not_Selected 的内容链接到预绑定的消息 obj:Message =Application.Current.Resources["Answer_Message_Not_Selected "].ToString() 但这不是动态的,我无法找到一种方法来创建可以更新消息的假设“OnAnswerMessageResourceChange”事件.
  • 我将为此创建另一个票证以避免混淆。再次感谢大家。

标签: c# wpf dictionary binding


【解决方案1】:

解决此问题的一种简单方法是使TextBlock 的输出主要取决于Message 属性。

例如,您可以将Text 的值绑定到Message,前提是Message 的值不为空,否则将其设置为您的资源:

<TextBlock Style="{StaticResource textReplyMessageStyle}">
    <Run x:Name="answerMessage" >
        <Run.Style>
            <Style TargetType="{x:Type Run}">
                
                <Setter Property="Text" Value="{Binding Message, Mode = OneWay, FallbackValue = ''}" />
                
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Message}" Value="{x:Null}">
                        <Setter Property="Text" Value="{StaticResource Answer_Message_Not_Selected}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Run.Style>
    </Run>  
</TextBlock>

请注意,您应该在样式内设置Text 的起始值,因为在控件初始化程序中设置的属性将覆盖任何样式设置器!

除了将Message 的值设置为null 之外,您还可以做的另一件事是在视图模型中添加属性AnswerMessageSelected,以便在TextBlock 应该更改其目标值时更加明确:

<TextBlock Style="{StaticResource textReplyMessageStyle}">
    <Run x:Name="answerMessage" >
        <Run.Style>
            <Style TargetType="{x:Type Run}">
                
                <Setter Property="Text" Value="{Binding Message, Mode = OneWay, FallbackValue = ''}" />
                
                <Style.Triggers>
                    <DataTrigger Binding="{Binding AnswerMessageSelected}" Value="False">
                        <Setter Property="Text" Value="{StaticResource Answer_Message_Not_Selected}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Run.Style>
    </Run>  
</TextBlock>

而且一般使用此方法后,可能不需要在后面的代码中使用x:Name 来引用,因为让 ViewModel 完成所有工作而不是 View 背后的代码是更好的做法:

<TextBlock>
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource textReplyMessageStyle}">

            <Setter Property="Text" Value="{Binding Message, Mode = OneWay, FallbackValue = ''}" />

            <Style.Triggers>
                <DataTrigger Binding="{Binding AnswerMessageSelected}" Value="False">
                    <Setter Property="Text" Value="{StaticResource Answer_Message_Not_Selected}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

【讨论】:

  • 感谢艾哈迈德,非常好的和干净的解决方案。不幸的是,我不能在我的情况下使用它,因为 TextBlock 对象在更大的用户控件中使用,该控件在需要各种类型的 Answer_Message_Not_Selected 消息的不同场景下使用。
  • @xSanciopanzax 将{StaticResource Answer_Message_Not_Selected} 更改为{DynamicResource Answer_Message_Not_Selected} 怎么样,之前我想更改颜色但同时将默认颜色设置为活动颜色模式时遇到了同样的问题(暗或亮)字典
【解决方案2】:

我最初的怀疑是正确的,感谢@Jason Tyler @o_w 确认。
当您设置对 Run 的引用(以及类似元素)时,您将丢失绑定属性。 我的问题的解决方法就是再次绑定。

Binding b = new Binding(); 
b.Path = new PropertyPath("Message"); 
b.Source = this;  
BindingOperations.SetBinding(answerMessage, Run.TextProperty, b);

此解决方案解决了问题,但可以通过将 Answer_Message_Not_Selected 资源设置为绑定的消息元素来解决问题。

Message = Application.Current.Resources["Answer_Message_Not_Selected "].ToString()

如果资源是动态的,比如在我的例子中,您将需要某种 OnChange 事件来观察资源(或字典)以保持 Message 的内容始终更新。

【讨论】:

    猜你喜欢
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多