WPF DataTrigger doesn't work.

2019-09-04 03:47发布

问题:

I designed a WPF Page and it should be possible to change the theme (dark theme and light theme). I am a newbie in WPF and found a solution to my problem using DataTrigger, but it don't works. 3 hours later I tried like 10 different solutions/tutorials but I don't know what I am doing wrong...

The xml code:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  xmlns:local="clr-namespace:VMQWPFApplication.Pages" x:Class="VMQWPFApplication.Pages.MainPage" 
  mc:Ignorable="d" 
  d:DesignHeight="400" d:DesignWidth="600"
Title="MainPage">

<Page.Resources>
    <Style x:Key="styleWithTrigger" TargetType="{x:Type Rectangle}">
        <Setter Property="Fill" Value="Blue"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding DarkTheme, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainPage}}}" Value="True">
                <Setter Property="Fill" Value="Red"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Page.Resources>

<DockPanel>
    <!--Toolbar-->
    ...

    <!--Body-->
    <Grid>
        <Rectangle Style="{StaticResource styleWithTrigger}"/>
    </Grid>
</DockPanel>

And here the cs:

namespace VMQWPFApplication.Pages
{
    /// <summary>
    /// Interaction logic for MainPage.xaml
    /// </summary>
    public partial class MainPage : Page
    {
        public bool DarkTheme { get; set; }

        public MainPage()
        {
            InitializeComponent();
            DarkTheme = false;
        }

        private void TestButton_Click(object sender, RoutedEventArgs e)
        {
            DarkTheme = true;
        }
    }
}

At the beginning the rectangle is blue, but it won't change.

回答1:

Your MainPage.xaml.cs file does not implement the INotifyPropertyChanged interface. To do so you should add/change the following:

public partial class MainPage : Page, INotifyPropertyChanged

#region INotifyPorpertyChanged Memebers 

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

#endregion

I would change your DarkTheme property to:

private bool _darkTheme;
public bool DarkTheme { get { return _darkTheme; } set { _darkTheme = value; NotifyPropertyChanged("DarkTheme"); }

Now when you update DarkTheme it will raise the Change Property Event. I would also put the DataContext into the Page make up:

DataContext="{Binding RelativeSource={RelativeSource Self}}"