1
votes

I'm try to change the style of a user control based on a local property. I've tried using dependency properties and implementing INotifyPropertyChanged but nothing is working. I'm new to WPF so I'm hoping it is something simple. Thanks for your help.

Style located in the ResourceDictionary of the user control .xaml file. If you remove the datatrigger the effect is applied correctly.

<Style x:Name="Showing" TargetType="Border">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsShowing}" Value="True">
        <Setter Property="Effect">
            <Setter.Value>
                <DropShadowEffect ShadowDepth="0"
                    Color="Orange"
                    Opacity="1"
                    BlurRadius="1"
                    Direction="100"/>                            
            </Setter.Value>
        </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>       

The PropertyChanged event is getting raised when the property changes.

Public Class ucLCGPulseWindowMini
    Implements INotifyPropertyChanged

    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    Public Shadows Sub OnPropertyChanged(sender As Object, e As PropertyChangedEventArgs)
        If Not e Is Nothing Then
            RaiseEvent PropertyChanged(Me, e)
        End If
    End Sub

    Private blnShowing As Boolean = False
    Public Property IsShowing() As Boolean
        Get
            Return blnShowing
        End Get
        Set(ByVal value As Boolean)
            blnShowing = value
            OnPropertyChanged(Me, New PropertyChangedEventArgs("IsShowing"))
        End Set
    End Property

After setting the IsShowing property to True at runtime, I can look at the border element in WPF Inspector and it sees the trigger but says IsShowing == True Value{x:Null}. However, if I look at the instance of the user control in WPF inspector it shows IsShowing = True

1
Are you sure IsShowing is doing proper change notification?Mark Feldman
You can see my implementation of INotifyPropertyChanged above. Does that look correct? As I mentioned, the PropertyChanged event is getting raised when the property is changed. Lastly, noticed that I defaulted blnShowing to False. I would have expected WPF inspector to reflect that not X:Null. I'm guessing this is a binding issue but I'm so new to WPF it is just a guess.ScottW
Sorry, my bad, didn't notice the change notification. It works fine for me, the only thing I had to change was setting the BlurRadius to 10 because 1 wasn't enough. You're specifying a key so you need to explicitly apply the style to each border that uses it, can you show the code where you're doing that?Mark Feldman
One second, is ucLCGPulseWindowMini a user control? The binding that you're using will be looking for the IsShowing property in the control's DataContext, not the control itself. If you want it to work you'll need to either 1) set the UserControl as it's own DataContext, 2) change the binding to do a RelativeSource FindAncestor, or 3) give your user control a name and specify that in ElementName in your binding. If you post your entire UserControl XAML I'll give you the exact changes you need to make.Mark Feldman
Yes, ucLCGPulseWindowMini is a user control. All the code above is in the user control .xaml file and the .vb code behind.ScottW

1 Answers

1
votes

Upgrading comment to an answer here...

1) To set the UserControl as its own DataContext just do a this.DataContext=this; in the constructor. You'll almost never want to do this for anything other than development/testing though because if the person using your control sets the DataContext to something else (i.e. to the data they actually want to display) then it will break all your bindings.

2) It will normally look something like this:

Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=your_namespace:ucLCGPulseWindowMini}, Path=IsShowing}" 

3) If you don't want to use FindAncestor then you give the user control a name and refer to it directly:

<UserControl
    x:Class="Your.NameSpace.ucLCGPulseWindowMini"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="myControl"
    d:DesignHeight="300" d:DesignWidth="300"
    >

   ... Binding="{Binding ElementName=myControl, Path=IsShowing}" ...