How to set a binding inside a style?

2019-05-09 10:06发布

问题:

I am fairly new to Xaml.
I am learning UWP(Universal Windows Platform) and I have more buttons and I want to bind their Background property to a property of a ViewModel that will change during some events.

I implemented the INotifyPropertyChanged and everything works ok (the color of the buttons change) when I bind the Background property in the Buttons' declaration in XAML:

<Button Content="0" Grid.Column="0" Grid.Row="5"
                Background="{Binding ButtonColor, Source={StaticResource AppViewModel}}" Style="{StaticResource BasicButton}"/>

StaticResource AppViewModel is a resource in App.xaml:

<Application.Resources>
    <viewModel:AppViewModel x:Key="AppViewModel" />
</Application.Resources>

I don't know how ok is to declare a ViewModel for App.xaml, but it's a solution I found for having global variables (the variables are held inside the viewModel).

Now back to my question: As I don't want to bind the Background on every single button, I tried to add it on the style like this:

<Style x:Key="BasicButton" TargetType="Button">
            <Setter Property="Background" Value="{Binding ButtonColor, Source={StaticResource AppViewModel}}" />
</Style>

But now when the color variable is changing during running the app, the UI doesn't update anymore. It seems that binded properties in styles don't respond to changes of variables.

What am I doing wrong? Thank you for any answers.

回答1:

After more searching I found a video from Jerry Nixon : http://blog.jerrynixon.com/2013/01/walkthrough-dynamically-skinning-your.html

It seems that because we don't have DynamicResource in uwp / winrt, we have to do a trick: We renavigate to the same frame. So after we change the property, we have to do something like this:

var frame = Window.Current.Content as Frame;
frame.Navigate(frame.Content.GetType());
frame.GoBack();

It's like invalidating a control in Windows Forms. It's making the UI redraw itself. I'm not sure if this has side effects, I'll have to dig more. I'll come back if I find any.