Reputation:
I am having a problem with data binding in XAML. I am just learning WPF, and after two days of research, I came up with this code:
C++/CX:
namespace App1
{
class buttonColor {
public:
buttonColor(Windows::UI::Color c) { foreground = c; }
Windows::UI::Color get() { return foreground; }
void set(Windows::UI::Color c) { foreground = c; }
private:
Windows::UI::Color foreground;
};
}
I call it with this:
MainPage::MainPage()
{
InitializeComponent();
buttonColor t(Windows::UI::Colors::Blue);
}
XAML:
<Page.Resources>
<CollectionViewSource x:Key="buttonColor" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" DataContext="{StaticResource buttonColor}">
<Button Content="Test" Foreground="{Binding Source=t}" />
</Grid>
This sort of works: it does change the foreground to a dull red, but I can't control the color change. Does anyone know why this is not changing to the colors I tell it in my C++/CX code?
Update:
I posted my full code on GitHub here: https://github.com/user2509848/wpf/tree/master. Right now, all I am getting is a linking error that _foreColorProperty
cannot be found. If anyone knows what I am doing wrong, please let me know.
Upvotes: 0
Views: 357
Reputation: 17085
Source=
or replace it with Path=
So instead of
<Button Content="Test" Foreground="{Binding t}" />
write:
<Button Content="Test"/>
<Button.Foreground>
<SolidColorBrush Color="{Binding t}"/>
</Button.Foreground>
</Button>
The reason you can't see the color changes, is your property does not notify the XAML about the changes.
In Header:
public:
static property Windows::UI::Xaml::DependencyProperty^ ForeColorProperty
{
Windows::UI::Xaml::DependencyProperty^ get()
{
return _foreColorProperty;
}
}
public:
property Windows::UI::Color^ ForeColor
{
Windows::UI::Color^ get()
{
return (Windows::UI::Color^)GetValue(ForeColorProperty);
}
void set(Windows::UI::Color^ value)
{
SetValue(ForeColorProperty, value);
}
}
In CPP:
DependencyProperty^ MainPage::_foreColorProperty = DependencyProperty::Register(
"ForeColor",
GetTypeName<Windows::UI::Color>(),
GetTypeName<MainPage>(),
ref new PropertyMetadata(nullptr));
Then use "{Binding ForeColor}"
to bind to this property.
DataContext
value of each FrameworkElement
is responsible for resolving the binding path. Which means in order to bind correctly you should first make sure DataContext
has the correct value. DataContext
always inherits its value from its parent which means if you set the DataContext
of MainPage
to something, DataContext
of Button will be equal to it unless set explicitly.
e.g. When you say <Button Foreground="{Binding t}">
you mean to set the foreground of Button to Button.DataContext.t
In this example DataContext
of Button is supposed to be equal to the current instance of MainPage
because we defined _foreColorProperty for this parent type: GetTypeName<MainPage>()
DependencyProperty^ MainPage::_foreColorProperty = DependencyProperty::Register(
"ForeColor",
GetTypeName<Windows::UI::Color>(),
--> GetTypeName<MainPage>(),
ref new PropertyMetadata(nullptr));
But that's not enough, You have to set it in the constructor of MainPage:
DataContext = this;
If we need another class as the ViewModel for the MainPage
we should create another class and add these properties to it (and change GetTypeName() too) and then
MyViewModelClass* vm = new MyViewModelClass();
DataContext = vm;
Upvotes: 1