0
votes

In WP8 app, i have few controls where i bind the foreground color which i am changing in the codebehind. But OnPropertyChanged is not firing when the user event happened.

I have defined this binding "ControlForeground" in my textblock and radiobutton data template controls in it. I am trying to change the Foreground color whenever user presses the button. But my new color assignment is not updating the UI. Anything i am missing here?

In XAML,

<TextBlock x:Name="lblTileColor" TextWrapping="Wrap" Text="Selected color:" Foreground="{Binding ControlForeground, Mode=TwoWay}"/>
<TextBlock x:Name="lblTileColor2" TextWrapping="Wrap" Text="App bg:" Foreground="{Binding ControlForeground, Mode=TwoWay}"/>
<RadioButton x:Name="accentColor" IsChecked="true" BorderBrush="White" Foreground="{Binding ControlForeground, Mode=TwoWay}">
                    <RadioButton.ContentTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Rectangle Width="25" Height="25" Fill="{StaticResource PhoneAccentBrush}"/>
                                <TextBlock Width="10"/>
                                <TextBlock x:Name="lblDefaultAccent" Text="Default accent color" Foreground="{Binding ControlForeground, Mode=TwoWay}"/>
                            </StackPanel>
                        </DataTemplate>
                    </RadioButton.ContentTemplate>
                </RadioButton>

<Button x:name="UpdateColor" click="update_btn"/>

In C#,

public class ColorClass : INotifyPropertyChanged
{
    private SolidColorBrush _ControlForeground;
    public SolidColorBrush ControlForeground
    {
        get
        {
            return _ControlForeground;
        }

        set
        {
            _ControlForeground = value;
            OnPropertyChanged("ControlForeground");
        }
    }

    public ColorClass() { }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

public class ColorPage:PhoneApplicationPage{

    public ObservableCollection<ColorClass> TestCollection { get; private set; }

    public void update_btn(object sender, EventArgs e){
            TestCollection.Add(new ColorClass()
            {
                ControlForeground = new SolidColorBrush(Colors.Red)
            });
    }

}
2
Have you set your data context? Normally I see this in .Net 4.0 with WPF when the class / view model does not have the datacontext set. - tsells
yes, i did set my data context in ColorPage class constructor.... this.DataContext = TestCollection; - Mahender
Have you set a breakpoint in the OnPropertyChanged method to see if it actually invokes the PropertyChanged delegate? - PoweredByOrange
i followed the @pantaloons answer below...and made some progress on my issue...see my latest comment under the below answer. - Mahender

2 Answers

1
votes

For your 2nd problem (not being able to bind controls inside your data template), this is because these controls will use the data context of the their parent template not the data context of the page.

To fix this, you'll have to tell these controls the element name with the data context and give it full path of your property.

<TextBlock 
    x:Name="lblDefaultAccent" 
    Text="Default accent color" 
    Foreground="{Binding DataContext.ControlForeground, 
                         ElementName=LayoutRoot, Mode=TwoWay}"/>

As you can see above you have to specify the element name. In case you bound this using this.DataContext = colorClass then the element name will be the name of the outer grid in your xaml, defaulted as LayoutRoot

1
votes

You can only bind an ObservableCollection to controls which expect it, like a ListBox or LongListSelector. Additionally, adding a Brush to the TestCollection doesn't fire the non-functional notification since it doesn't call the setter of that property, just modifies the existing object.

Make TestCollection a type ColorClass and change the .Add stuff to just change the ColorClass.ControlForeground property and this should "just work."