C
C#•11h ago
pauliology

Fancy Button color change.

Hi all, I am trying to change the color of a button background. It is initially set via a custom control using the <setter> tag as a template like so:
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/>
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/>
I am now using a function to change the background color yet it is not working. I am assuming the <setter> is overriding my color change. This is the example code
public async Task AllAtOnce()
{
List<Task<PingReply>> tasksWeStarted = new();

tasksWeStarted.Add(Task.Run(() => DoPing("10.221.67.56"))); // Radio

await Task.WhenAll(tasksWeStarted);

// Check the results of each ping
RadioBorder.Background = tasksWeStarted[0].Result.Status == IPStatus.Success ? Brushes.LimeGreen : Brushes.Crimson;
}
public async Task AllAtOnce()
{
List<Task<PingReply>> tasksWeStarted = new();

tasksWeStarted.Add(Task.Run(() => DoPing("10.221.67.56"))); // Radio

await Task.WhenAll(tasksWeStarted);

// Check the results of each ping
RadioBorder.Background = tasksWeStarted[0].Result.Status == IPStatus.Success ? Brushes.LimeGreen : Brushes.Crimson;
}
This is the xaml reference
<CustomControls:FancyButton x:Name="RadioBorder" />
<CustomControls:FancyButton x:Name="RadioBorder" />
Could you give me some guidance as to why the background color isn't changing yet the foreground changes as you can see the red text. Here is a link to the sample reference code. https://paste.mod.gg/ixhwhtdewdjs/2 Thank you
BlazeBin - ixhwhtdewdjs
A tool for sharing your source code with the world!
No description
No description
67 Replies
Pope
Pope•10h ago
Let me know how this is:
<UserControl x:Class="Wpf.Sandbox.ButtonColorTest.ButtonTest"
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:Wpf.Sandbox.ButtonColorTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ButtonTestViewModel}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button x:Name="MyButton"
Width="150"
Height="50"
Content="Click Me"
Background="{Binding ButtonBackground}"
Command="{Binding ClickedButtonCommand}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</StackPanel>
</StackPanel>
</UserControl>
<UserControl x:Class="Wpf.Sandbox.ButtonColorTest.ButtonTest"
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:Wpf.Sandbox.ButtonColorTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:ButtonTestViewModel}">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button x:Name="MyButton"
Width="150"
Height="50"
Content="Click Me"
Background="{Binding ButtonBackground}"
Command="{Binding ClickedButtonCommand}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</StackPanel>
</StackPanel>
</UserControl>
with a viewmodel:
public partial class ButtonTestViewModel : ObservableObject
{
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.Blue;

[RelayCommand]
private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
}
public partial class ButtonTestViewModel : ObservableObject
{
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.Blue;

[RelayCommand]
private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
}
proof of concept that doesn't exactly work with what you have going on, which is having many buttons which shouldn't tie to many properties I think people will look down on me referencing colors directly in the VM.
pauliology
pauliologyOP•10h ago
I will only elevate you mate, thank you for even taking a look
Pope
Pope•10h ago
Here's your situation fleshed out
Pope
Pope•10h ago
BlazeBin - uabmzbdugxbb
A tool for sharing your source code with the world!
Pope
Pope•10h ago
pauliology
pauliologyOP•10h ago
Thank you I was trying to make your code work
Pope
Pope•10h ago
I took out a lot of code related to this stuff: AddingCalculatorViewModel addingCalculatorViewModel, WeekViewModel weekViewModel, DiffViewModel diffViewModel, ButtonTestViewModel buttonTestViewModel If you see it, ignore it. I might have deleted more than I should. In which case you can ask. I'll give you one more file that can help.
pauliology
pauliologyOP•10h ago
No worries Im just reading your code trying to make sense of it and adapt it to my own
Pope
Pope•10h ago
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Wpf.Sandbox.ButtonColorCollectionTest;
using Wpf.Sandbox.ButtonColorTest;
using Wpf.Sandbox.Services.Configuration;

namespace Wpf.Sandbox;

public partial class App
{
private ServiceProvider Services { get; }
public App()
{
var services = new ServiceCollection();
ConfigureServices(services);
Services = services.BuildServiceProvider();
}

private static void ConfigureServices(ServiceCollection services)
{
services.AddSingleton<ButtonTestViewModel>();
services.AddSingleton<ButtonColorCollectionViewModel>();
services.AddSingleton<MainWindowViewModel>();
services.AddTransient<MainWindowView>();
}

private void Application_Startup(object sender, StartupEventArgs e)
{
var mainWindowView = Services.GetRequiredService<MainWindowView>();
mainWindowView.Show();
}
}
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Wpf.Sandbox.ButtonColorCollectionTest;
using Wpf.Sandbox.ButtonColorTest;
using Wpf.Sandbox.Services.Configuration;

namespace Wpf.Sandbox;

public partial class App
{
private ServiceProvider Services { get; }
public App()
{
var services = new ServiceCollection();
ConfigureServices(services);
Services = services.BuildServiceProvider();
}

private static void ConfigureServices(ServiceCollection services)
{
services.AddSingleton<ButtonTestViewModel>();
services.AddSingleton<ButtonColorCollectionViewModel>();
services.AddSingleton<MainWindowViewModel>();
services.AddTransient<MainWindowView>();
}

private void Application_Startup(object sender, StartupEventArgs e)
{
var mainWindowView = Services.GetRequiredService<MainWindowView>();
mainWindowView.Show();
}
}
and app.xaml:
<Application x:Class="Wpf.Sandbox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"/>
<Application x:Class="Wpf.Sandbox.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"/>
So basically, the WPF starts up. It doesn't open a window directly Instead, it runs App() because it's the entry point App then creates a bunch of services as singletons. Then it creates the ViewModel, then the View. Then from the app.xaml, it seeds it needs to run Application_Startup, which will grab the MainWindowView's required services based on the mainwindowView constructor which is here:
public partial class MainWindowView
{
public MainWindowView(MainWindowViewModel mainWindowViewModel)
{
DataContext = mainWindowViewModel;
InitializeComponent();
}
}
public partial class MainWindowView
{
public MainWindowView(MainWindowViewModel mainWindowViewModel)
{
DataContext = mainWindowViewModel;
InitializeComponent();
}
}
pauliology
pauliologyOP•10h ago
Yup
Pope
Pope•10h ago
then it shows the window. Great, we have mainWindow, but not the tab that matters. So we inject a new ButtonColorCollectionViewModel with the help of the services created in App() It's set as a property I put the stuff you care about in a TabControl, and it's just one of the many tabs but WPF doesn't know how to show a viewmodel directly. So I added some resources to the MainWindowView's Window's resources
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonColorCollectionViewModel}">
<buttonColorCollectionTest:ButtonColorCollectionView />
</DataTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonColorCollectionViewModel}">
<buttonColorCollectionTest:ButtonColorCollectionView />
</DataTemplate>
which is more or less "If I'm trying to show ButtonColorCollectionViewModel", then show ButtonColorCollectionView in its place, using that viewModel as the DataContext" The constructor for the view is simple, and I only removed a bunch of boilerplate from it:
public partial class ButtonColorCollectionView
{
public ButtonColorCollectionView() => InitializeComponent();
}
public partial class ButtonColorCollectionView
{
public ButtonColorCollectionView() => InitializeComponent();
}
You don't see it, but the DataContext has been automagically set behind the scenes for you When ButtonColorCollectionViewModel was instantiated, it ran the constructor, which creates 12 instances of ButtonItemViewModel, which has a shitty default color. ButtonItemViewModel doesn't have a corresponding View, because I was lazy. I just used a DataTemplate. You could easily extract it into its own component.
pauliology
pauliologyOP•10h ago
Forgive me for what I am about to say as I am reading your code and comparing the differences to that of my own
Pope
Pope•10h ago
I'd recommend setting up a separate project to match my own, then play with it. Then you can slowly integrate it into your solution.
pauliology
pauliologyOP•10h ago
So it looks like I need to have an ObservableObject which then changes the property
Pope
Pope•10h ago
I set up a bunch of test/example projects in my solution so I can just unload them later, but still use them as a reference sometimes.
No description
Pope
Pope•10h ago
Yeah, that comes from MVVM Community Toolkit. I'm lazy to set up INotifyPropertyChanged myself.
pauliology
pauliologyOP•10h ago
thats ok 😄
Pope
Pope•10h ago
having ObservableObject with partial implements that with SetValue (I think). [ObservableProperty] creates a property in addition to the field I defined. Fields are bad. There's a new fancy way of doing it in .NET 9, but I don't know it.
pauliology
pauliologyOP•10h ago
I have also noticed that as you stated, I don't actually use the Button Backround but just a Border Background
Pope
Pope•10h ago
Oh, is that the crux of the issue? 😄 I didn't really read your question tbh. I'm good at formulating questions, not reading them.
pauliology
pauliologyOP•10h ago
No no
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/> <!-- This seems to be the culprit that changes the background color -->
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/> <!-- This seems to be the culprit that changes the background color -->
That setter tag seems to change the entire background colour of the button so if i manually change value to red for example button goes red
Pope
Pope•10h ago
Here's a fun one for you:
public partial class ButtonColorCollectionViewModel : ObservableObject
{
public ObservableCollection<ButtonItemViewModel> Buttons { get; } = [];
private readonly DispatcherTimer _timer;
public ButtonColorCollectionViewModel()
{
for (var i = 0; i < 12; i++) { Buttons.Add(new ButtonItemViewModel { ButtonText = $"{i}- Click Me", }); }
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object? sender, EventArgs e)
{
var buttonsToPick = Random.Shared.Next(1, 4);
foreach (var button in Buttons.OrderBy(_ => Random.Shared.Next()).Take(buttonsToPick)) { button.ClickedButtonCommand.Execute(null); }
}
}
public partial class ButtonColorCollectionViewModel : ObservableObject
{
public ObservableCollection<ButtonItemViewModel> Buttons { get; } = [];
private readonly DispatcherTimer _timer;
public ButtonColorCollectionViewModel()
{
for (var i = 0; i < 12; i++) { Buttons.Add(new ButtonItemViewModel { ButtonText = $"{i}- Click Me", }); }
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object? sender, EventArgs e)
{
var buttonsToPick = Random.Shared.Next(1, 4);
foreach (var button in Buttons.OrderBy(_ => Random.Shared.Next()).Take(buttonsToPick)) { button.ClickedButtonCommand.Execute(null); }
}
}
Pope
Pope•10h ago
Pope
Pope•10h ago
I think this might be a bit closer to what you envisioned since you're pinging IP addresses for your security cameras or whatever. Eventually, you can change it from being a button to being an image and a button underneath called "UpdateFeedThumbnail" or something or "OpenFeedDiagnostics" Then you can open up a new window and see when's the last time you had a connection to it or get some other details about it. Maybe where you stored the video.
pauliology
pauliologyOP•10h ago
fuck i'd really love to be able to sit down with you and go over everything!!!! i shouldn't been asleep already im on night shift and im awake because i don't get the chance to do this while im at work
Pope
Pope•10h ago
I only really have one meaningful property created on the ButtonItemViewModel: ```cs [ObservableProperty] private string _buttonText = "Click me!"; ``` but I imagine you're going to be storing an IP address in there or something, so you're not switching stuff based on Random.Shared.NextDouble() < 0.5`
pauliology
pauliologyOP•10h ago
Yeah
Pope
Pope•10h ago
from the code I gave you, I think one bad practice I did was initiating the behavior of the viewModel before the tab is ever activated. so when I open the application and switch to the tab after 5 seconds elapses, everything is already colorful.
pauliology
pauliologyOP•10h ago
Looking at your way of doing it, i'd have to actually rewrite my entire custom control for my button altogether
Pope
Pope•10h ago
I should have added this to the ViewModel with the collections:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding UserControlLoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding UserControlLoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
and then created a [RelayCommand] that'll get hit by that. That way you're not doing network stuff when you don't have to. I think I could also pause the pinging when the tab isn't open with another event like "closed"
pauliology
pauliologyOP•10h ago
that makes fantastic sense
Pope
Pope•10h ago
Unloaded
Pope
Pope•9h ago
I added this to the UserContnrol
No description
pauliology
pauliologyOP•9h ago
Out of curiousity in my version of the example. (This is for my clarification), does the RadioButton.Foreground only work because it hasn't been set by the style in the template
Pope
Pope•9h ago
then F12 on Loaded and looked for other words, since F4/Properties doesn't work for me oh, for RadioButton?
pauliology
pauliologyOP•9h ago
Where as the Radio.Button has been ? Yeah let me show you what its doing one moment
Pope
Pope•9h ago
I don't think I've ever styled one.
pauliology
pauliologyOP•9h ago
pauliology
pauliologyOP•9h ago
Keep an eye out for the 3 that change to red Those have the .Foreground property being changed the first two boxes have the .Background
Pope
Pope•9h ago
Is that the desired behavior?
pauliology
pauliologyOP•9h ago
The desired behaviour is for the background to change I was merely testing
Pope
Pope•9h ago
Ahh, ok.
pauliology
pauliologyOP•9h ago
to show you that the code is actually doing something just not actually invoking the changed background colour yet it does foreground which is odd ?
Pope
Pope•9h ago
I think you should show the full code for one item. I'm not sure how it's set up. or is everything just in a Border?
pauliology
pauliologyOP•9h ago
Everything is in a border did you not see my full code ?
pauliology
pauliologyOP•9h ago
BlazeBin - norykmlilyrt
A tool for sharing your source code with the world!
Pope
Pope•9h ago
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border Background="{Binding ButtonBackground}" CornerRadius="15" Cursor="Hand">
<Button Width="120" Height="50"
Margin="5"

Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border Background="{Binding ButtonBackground}" CornerRadius="15" Cursor="Hand">
<Button Width="120" Height="50"
Margin="5"

Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
No description
pauliology
pauliologyOP•9h ago
That has the example button which i made a template, the xaml for the use of the button and the code behind it
Pope
Pope•9h ago
I saw the opening tags of the xaml, but not the ending I think maybe you have a bunch of hard-coded xaml for each button you need, right?
pauliology
pauliologyOP•9h ago
Yes sir
Pope
Pope•9h ago
I put all of mine in a collection, then present them in a WrapPanel, so I can do this:
No description
pauliology
pauliologyOP•9h ago
<Button.Template>
<ControlTemplate>
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/> <!-- This seems to be the culprit that changes the background color -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ccffffff"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<Image Grid.Row="0" Source="{Binding Image, ElementName=root}" Width="50" Height="50"/>

<TextBlock Grid.Row="1" FontWeight="Medium" FontSize="15" Margin="0,8" Text="{Binding Title, ElementName=root}" HorizontalAlignment="Center"/>

<ContentPresenter Grid.Row="2" Content="{Binding Content, ElementName=root}">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="FontSize" Value="12"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button.Template>
<ControlTemplate>
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#99ffffff"/> <!-- This seems to be the culprit that changes the background color -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#ccffffff"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<Image Grid.Row="0" Source="{Binding Image, ElementName=root}" Width="50" Height="50"/>

<TextBlock Grid.Row="1" FontWeight="Medium" FontSize="15" Margin="0,8" Text="{Binding Title, ElementName=root}" HorizontalAlignment="Center"/>

<ContentPresenter Grid.Row="2" Content="{Binding Content, ElementName=root}">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="FontSize" Value="12"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
this was the complete button template
Pope
Pope•9h ago
ok. I made a small change in my ItemTemplate
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding ButtonBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button Width="120" Height="50"
Margin="5"
Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding ButtonBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button Width="120" Height="50"
Margin="5"
Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This allows the border to be magenta'd when it's hovered over
Pope
Pope•9h ago
No description
Pope
Pope•9h ago
so I had to move where I was originally coloring the Border's background to be in a Style like you have it.
pauliology
pauliologyOP•9h ago
i see
Pope
Pope•9h ago
my trigger for the buttonBackground doesn't work in the xaml shown above Doing that is too complicated for me.
pauliology
pauliologyOP•9h ago
thats ok
Pope
Pope•9h ago
I'd end up doing something gnarly and shitty. It's more XAML than I care to maintain, so I'd push back on it.
pauliology
pauliologyOP•9h ago
You have shown me more than enough
Pope
Pope•9h ago
I'm going to sleep now. Questions like this are better suited for #gui , but responses are slower.
pauliology
pauliologyOP•9h ago
The binding code is still the same i believe
Pope
Pope•9h ago
I missed your question in #chat because someone posted a link after your question and I focused on that. I usually look at #gui whenever there's a new message and help with easy questions.
pauliology
pauliologyOP•9h ago
So your updated version where the setter value is being bound ButtonBackground binding still getting it from here
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.LightGray;
[ObservableProperty] private string _buttonText = "Click me!";
[RelayCommand] private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.LightGray;
[ObservableProperty] private string _buttonText = "Click me!";
[RelayCommand] private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
is that correct ?
Pope
Pope•9h ago
public partial class ButtonColorCollectionView
{
public ButtonColorCollectionView() => InitializeComponent();
}

public partial class ButtonColorCollectionViewModel : ObservableObject
{
public ObservableCollection<ButtonItemViewModel> Buttons { get; } = [];
private readonly DispatcherTimer _timer;
public ButtonColorCollectionViewModel()
{
for (var i = 0; i < 12; i++) { Buttons.Add(new ButtonItemViewModel { ButtonText = $"{i}- Click Me", }); }
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object? sender, EventArgs e)
{
var buttonsToPick = Random.Shared.Next(1, 4);
foreach (var button in Buttons.OrderBy(_ => Random.Shared.Next()).Take(buttonsToPick)) { button.ClickedButtonCommand.Execute(null); }
}
}

public partial class ButtonItemViewModel : ObservableObject
{
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.LightGray;
[ObservableProperty] private string _buttonText = "Click me!";
[RelayCommand] private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
}
public partial class ButtonColorCollectionView
{
public ButtonColorCollectionView() => InitializeComponent();
}

public partial class ButtonColorCollectionViewModel : ObservableObject
{
public ObservableCollection<ButtonItemViewModel> Buttons { get; } = [];
private readonly DispatcherTimer _timer;
public ButtonColorCollectionViewModel()
{
for (var i = 0; i < 12; i++) { Buttons.Add(new ButtonItemViewModel { ButtonText = $"{i}- Click Me", }); }
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object? sender, EventArgs e)
{
var buttonsToPick = Random.Shared.Next(1, 4);
foreach (var button in Buttons.OrderBy(_ => Random.Shared.Next()).Take(buttonsToPick)) { button.ClickedButtonCommand.Execute(null); }
}
}

public partial class ButtonItemViewModel : ObservableObject
{
private static readonly SolidColorBrush GoodColor = Brushes.LimeGreen;
private static readonly SolidColorBrush BadColor = Brushes.Crimson;

[ObservableProperty] private SolidColorBrush _buttonBackground = Brushes.LightGray;
[ObservableProperty] private string _buttonText = "Click me!";
[RelayCommand] private void ClickedButton() => ButtonBackground = Random.Shared.NextDouble() < 0.5 ? GoodColor : BadColor;
}
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding ButtonBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button Width="120" Height="50"
Margin="5"
Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Buttons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type buttonColorCollectionTest:ButtonItemViewModel}">
<Border CornerRadius="15" Cursor="Hand">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding ButtonBackground}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Magenta"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button Width="120" Height="50"
Margin="5"
Command="{Binding ClickedButtonCommand}"
Content="{Binding ButtonText}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
pauliology
pauliologyOP•9h ago
yeah awesome
Pope
Pope•9h ago
<UserControl x:Class="Wpf.Sandbox.ButtonColorCollectionTest.ButtonColorCollectionView"
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:buttonColorCollectionTest="clr-namespace:Wpf.Sandbox.ButtonColorCollectionTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance Type=buttonColorCollectionTest:ButtonColorCollectionViewModel}" >
<Grid>
<!-- what I just shared -->
</Grid>
</UserControl>
<UserControl x:Class="Wpf.Sandbox.ButtonColorCollectionTest.ButtonColorCollectionView"
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:buttonColorCollectionTest="clr-namespace:Wpf.Sandbox.ButtonColorCollectionTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance Type=buttonColorCollectionTest:ButtonColorCollectionViewModel}" >
<Grid>
<!-- what I just shared -->
</Grid>
</UserControl>

Did you find this page helpful?