I know that something similar has been asked here and I have read those answers… but none of them relates to my case, I think.
So, I have a WPF application already developed and I wanted to start developing my own UserControls, instead of putting all the XAML controls directly in the Pages, in order to have ready-to-use piece of UI across the entire application itself.
Now, here it is the relevant code of my UserControl XAML:
<UserControl x:Class="DigitalColorimeter.Controls.ColorViewer"
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:DigitalColorimeter.Controls"
mc:Ignorable="d"
d:DesignHeight="155" d:DesignWidth="125">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="TestoTitle" Text="{Binding Title, Mode=OneWay}" FontSize="16" FontWeight="Bold"/>
<Rectangle x:Name="AreaColore" Grid.Row="1" Fill="{Binding ColorBrush, Mode=OneWay}"/>
// Other controls...
<TextBlock x:Name="TestoColorString" Grid.Row="5" Grid.ColumnSpan="3" Text="#FF223344" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,4,0,0" TextWrapping="Wrap"/>
</Grid>
</UserControl>
Here we have instead the UserControl's class:
public partial class ColorViewer : UserControl
{
public ColorViewer()
{
InitializeComponent();
}
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set
{
SetValue(ColorProperty, value);
Debug.WriteLine("--- COLOR changed!");
// Updating other properties:
ColorBrush = new SolidColorBrush(value);
UpdateColorProperties(value);
}
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(Color), typeof(ColorViewer), null);
public SolidColorBrush ColorBrush
{
get { return (SolidColorBrush)GetValue(ColorBrushProperty); }
set { SetValue(ColorBrushProperty, value); }
}
public static readonly DependencyProperty ColorBrushProperty =
DependencyProperty.Register("ColorBrush", typeof(SolidColorBrush), typeof(ColorViewer), null);
public String Title
{
get { return (String)GetValue(TitleProperty); }
set
{
SetValue(TitleProperty, value);
UpdateTitle(value);
}
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(String), typeof(ColorViewer), null);
private void UpdateTitle(string s)
{
if (s == "")
{
TestoTitle.Visibility = Visibility.Collapsed;
}
else
{
TestoTitle.Visibility = Visibility.Visible;
}
}
private void UpdateColorProperties(Color c)
{
Debug.WriteLine("UPDATE COLOR | color: " + c.ToString());
AreaColore.Fill = new SolidColorBrush(c);
ColorBrush = new SolidColorBrush(c);
TestoColorString.Text = c.ToString();
}
}
...and here it is the first page where I'm testing it all (the UserControl is called "ColorViewer", the ExtendedWPF is a Nuget library...):
<Page x:Class="DigitalColorimeter.View.PaginaSelettoreControl"
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:DigitalColorimeter.View"
xmlns:ExtendedWPF="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:controls="clr-namespace:DigitalColorimeter.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Picker control page">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Grid.ColumnSpan="2" Text="{Binding TestoTest, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="5" />
<ExtendedWPF:ColorCanvas Grid.Row="1" x:Name="SelettoreControl" SelectedColor="{Binding ColorSelected, Mode=TwoWay}" Margin="25" HorizontalAlignment="Center"/>
// Other controls…
<controls:ColorViewer Grid.Row="1" Grid.Column="1" Width="175" Color="{Binding ColorSelected, Mode=OneWay}" Title="{Binding TestoTest, Mode=OneWay}" Margin="15"/>
</Grid>
</ScrollViewer>
So, here's my idea: I want that the UserControl's "Color" property updates even the "TestoColorString" textblock (with the color's string, of course) and the color shown in the "AreaColore" rectangle.
The problems are that:
when ColorSelected changes in the AppViewModel (and it does, i tested it), the UserControl DOESN'T receive it
I don't know exactly the correct way to update other dependency properties depending on one of them (you can see some function called in the backcode of the set method of the "Color"'s property… but I am not sure it is good in that way.
The TextBox in the page, inserted in order to test "Title" property of the UserControl, DOESN'T allow to modify its text! The only changes that I can do is inserting white spaces or deleting characters! And it does this whetever it is binded to something or not!
Hope that I explained it all well… I'm completely stuck.
Thank for your attention, if you need some more infos, please comment.
Best regards