Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
53 views
in Technique[技术] by (71.8m points)

c# - How to remove a dictionary resource reference from a TextBlock?

I have this element:

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

And I have the need to print in answerMessage either the content of the var Message (thanks to the binding) or an element from the dictionary (thanks to resource reference done by the code below).

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

The binding is fully working as well as the dictionary reference, but after setting the resource reference once I can not find a way to make the binding work again.

I tried to re-do the binding programmatically but is not working... The only working workaround I found is to set programmatically the text of answerMessage.
How can I remove the resource reference from the Run element and make the binding work again?

Just to give a bit of context the variable Message contains a number and the resource Answer_Message_Not_Selected contains the text "Not selected" or a translation in a different language depending on the dictionary active on the program. I have to use dynamic resource reference because the language of the program can be changed on the fly.

Thanks!

question from:https://stackoverflow.com/questions/65601542/how-to-remove-a-dictionary-resource-reference-from-a-textblock

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A simple way to work this around is to make the output of the TextBlock depends mainly on the Message property.

For example, you can bind the value of Text to Message only if the value of Message is not null, otherwise set it to your resource:

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

Notice that you should set the starting value of Text inside the style because properties set in the control initializer will override any style setters!

Another thing you can do instead of setting the value of Message to null is to add a property AnswerMessageSelected in the view model, to be more explicit when the TextBlock should change its target value:

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

And generally after using this method, it might not be necessary to use x:Name to refer to in the code behind, since it's a better practice to let the ViewModel do all the work and not the code behind the 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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...