I'm trying to update the background color of some custom controls I created, based on the values from an observable collection bound to the XAML through a data template, but the bindings get wrong values after the collection changes. The other properties get updated correctly. See the end of the post for new important info
I tried changing the property name and applying the template every time a property changed, but it didn't work.
CustomControls(project)/Themes/Generic.xaml
:
<Style TargetType="local:CustomTableCard">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomTableCard">
<Grid Height="300" Width="300" BorderThickness="4" Background="{Binding BackgroundColorProp, RelativeSource={RelativeSource TemplatedParent},
Mode=OneWay, FallbackValue='Black', TargetNullValue='Blue'}">
CustomControls/CustomTableCard.cs
public class CustomTableCard : Control
{
public static readonly DependencyProperty BackgroundColorProperty =
DependencyProperty.Register(
nameof(BackgroundColorProperty),
typeof(string),
typeof(CustomTableCard),
new PropertyMetadata(null));
public string BackgroundColorProp
{
get => (string)GetValue(BackgroundColorProperty);
set => SetValue(BackgroundColorProperty, value);
}
public CustomTableCard()
{
this.DefaultStyleKey = typeof(CustomTableCard);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
[...]
}
View(Packaged project)/CustomTablePage.xaml
:
<Page.Resources>
<DataTemplate x:Key="CustomTableItemTemplateNew" x:DataType="Data:CustomTableCardData">
<ItemContainer>
<customControls:CustomTableCard TableName="{x:Bind TableNameData, Mode=OneWay}"
TextColor="{x:Bind TextColorData, Mode=OneWay}"
[...]
BackgroundColorProp="{x:Bind BackgroundColorData}"
TableDeletionRequested="CustomTableItem_TableDeletionRequested"
/>
</ItemContainer>
</DataTemplate>
</Page.Resources>
[...]
<ItemsView x:Name="itemsViewTables" HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource CustomTableItemTemplateNew}"
ItemsSource="{x:Bind Data:CustomTableCardDataRepository.customTableItemsCollection, Mode=OneWay}"
View/CustomTablePage.xaml.cs
:
public void loadTables()
{
CustomTableCardDataRepository.FillCustomTablesCollection((int)userId);
itemsViewTables.ItemsSource = CustomTableCardDataRepository.customTableItemsCollection;
}
Even though the data in customTableItemsCollection
is correct before and after it's assigned to items source, the binding for the grid background gets an incorrect value.
Page just loaded with the data from loadTables()
New tables added without reloading the whole page. Just called loadTables()
and filled the customTableItemsCollection
with the correct data:
It feels like the colors somehow get mixed between the controls. Then if I simply switch pages and go back to that one, everything gets displayed correctly again:
Sometimes, all buttons get green backgrounds:
But When I debug, I can see the first button's property is being set to white in CustomControls/CustomTableCard.cs
:
The first button is bound to the correct property but it's not the right color
Data in itemsSource:
I also got this after restarting the app and removing the other button(card). I have no idea where it's getting this color from if there aren't any other buttons. It couldn't be a data mix, I suppose? Unless it's getting the previous data somehow.
New info:
I experimented changing the default button color and it changed the bugged color as well
I debbuged the constructor code but it never reached the line that sets the property to pink when there was only the first button(image above), instead it set the property to white, which is the correct data.
Data(project)/CustomTableCard.cs
With that, I think it's fairly accurate to say that it's getting previous data from other buttons that were removed. The binding is probably bugged. I don't know how to approach this issue though...
The DependencyProperty is not correct.
Try the following:
public static readonly DependencyProperty BackgroundColorPropProperty =
DependencyProperty.Register(
nameof(BackgroundColorProp),
typeof(string),
typeof(CustomTableCard),
new PropertyMetadata(null));
public string BackgroundColorProp
{
get => (string)GetValue(BackgroundColorPropProperty);
set => SetValue(BackgroundColorPropProperty, value);
}