Ellipse as radio button - c#

In my project, I have a little color picker that is in fact an ItemsControl with SolidColorBrushes as items, and an Ellipse as ItemTemplate.
I want the user to pick a color, when he clicks the Ellipse I want the BorderThickness to go from 0 to 2, in order to highlight the selected Ellipse.
I already managed to change the BorderThickness when the user hovers the item, using triggers. But where would I save the information about which color is selected? I can not really think of an approach here. And how can I manage that the trigger on hovering still fires even when the trigger for selected has already been activated?
Thanks in advance.

Here's some markup and code to consider.
The Selected item of the listbox is also made the current item of the collectionview. You can bind that, get it in code in the viewmodel and also navigate to next and previous.
https://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.currentitem%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
I bind the rectangle to the current brush so when you select a different entry that changes. The listbox already has a lightblue background appears as you mouseover an item which highlights it somewhat. My trigger also increases the size of the ellipse a bit.
<Window.DataContext>
<local:MainWIndowViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding BrushesView}"
IsSynchronizedWithCurrentItem="True"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{Binding}" Height="20" Width="20">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Stroke" Value="Gray"/>
<Setter Property="StrokeThickness" Value="1"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}"
Value="True">
<Setter Property="Ellipse.Stroke" Value="Black"/>
<Setter Property="Ellipse.StrokeThickness" Value="2"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.2" ScaleY="1.2" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Rectangle
Grid.Column="1"
Width="40"
Height="40"
Fill="{Binding BrushesView/}"/>
</Grid>
The viewmodel:
public class MainWIndowViewModel
{
public CollectionView BrushesView { get; set; }
private ObservableCollection<SolidColorBrush> BrushesList { get; set; } =
new ObservableCollection<SolidColorBrush>
{
Brushes.Yellow, Brushes.Pink, Brushes.Blue, Brushes.Green, Brushes.Red, Brushes.Purple
};
public MainWIndowViewModel()
{
BrushesView = (CollectionView)new CollectionViewSource { Source = BrushesList }.View;
}
}

Related

How to persistently change color of ListBox SelectedItem after selecting

I have a listbox that loads it's items with Foreground color set to red. What I'd like to do is: upon selecting an item with the mouse, change the foreground color of SelectedItem to black, but make the change persistent so that after deselecting the item, color remains black. Incidentally I want to implement this as a way of showing 'read items' to the user.
Essentially I want something like an implementation of the common property trigger like the code below, but not have the style revert after deselection. I've played around with event triggers as well without much luck.
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="Foreground" Value="Black" /> //make this persist after deselection
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
Thanks in advance!
You could animate the Foreground property:
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)"
To="Black" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The downside of this simple approach is that the information is not stored somewhere. This is pure visualization without any data backing. In order to persist the information, so that restarting the application shows the same previous state, you should introduce a dedicated property to your data model e.g IsMarkedAsRead.
Depending on your requirements, you can override the ListBoxItem.Template and bind ToggleButton.IsChecked to IsMarkedAsRead or use a Button which uses a ICommand to set the IsMarkedAsRead property. There are many solutions e.g. implementing an Attached Behavior.
The following examples overrides the ListBoxItem.Template to turn the ListBoxItem into a Button. Now when the item is clicked the IsMarkedAsRead property of the data model is set to true:
Data model
(See Microsoft Docs: Patterns - WPF Apps With The Model-View-ViewModel Design Pattern for an implementation example of the RelayCommand.)
public class Notification : INotifyPropertyChanged
{
public string Text { get; set; }
public ICommand MarkAsReadCommand => new RelayCommand(() => this.IsMarkedAsRead = true);
public ICommand MarkAsUnreadCommand => new RelayCommand(() => this.IsMarkedAsRead = false);
private bool isMarkedAsRead;
public bool IsMarkedAsRead
{
get => this.isMarkedAsRead;
set
{
this.isMarkedAsRead = value;
OnPropertyChanged();
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
ListBox
<ListBox ItemsSource="{Binding Notifications}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Background="{TemplateBinding Background}">
<Button x:Name="ContentPresenter"
ContentTemplate="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=ItemTemplate}"
Content="{TemplateBinding Content}"
Command="{Binding MarkAsReadCommand}"
Foreground="Red">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border>
<ContentPresenter />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsMarkedAsRead}" Value="True">
<Setter TargetName="ContentPresenter" Property="Foreground" Value="Green" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type Notification}">
<TextBlock Text="{Binding Text}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Thanks a lot #BionicCode for the comprehensive answer. I ended up going with another solution which may or may not be good convention; I am a hobbyist.
Firstly, I don't need databacking / persistence.
Concerning the data model solution and overriding ListBoxItem.Template, I am using a prededfined class 'SyndicationItem' as the data class (my app is Rss Reader). To implement your datamodel solution I guess I could hack an unused SyndicationItem property, or use SyndicationItem inheritance for a custom class (I'm guessing this is the most professional way?)
My complete data model is as follows:
ObservableCollection >>> CollectionViewSource >>> ListBox.
Anyway I ended up using some simple code behind which wasn't so simple at the time:
First the XAML:
<Window.Resources>
<CollectionViewSource x:Key="fooCollectionViewSource" Source="{Binding fooObservableCollection}" >
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="PublishDate" Direction="Descending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style x:Key="DeselectedTemplate" TargetType="{x:Type ListBoxItem}">
<Setter Property="Foreground" Value="Gray" />
</Style>
</Window.Resources>
<ListBox x:Name="LB1" ItemsSource="{Binding Source={StaticResource fooCollectionViewSource}}" HorizontalContentAlignment="Stretch" Margin="0,0,0,121" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<TextBlock MouseDown="TextBlock_MouseDown" Grid.Column="0" Text="{Binding Path=Title.Text}" TextWrapping="Wrap" FontWeight="Bold" />
<TextBlock Grid.Column="1" HorizontalAlignment="Right" TextAlignment="Center" FontSize="11" FontWeight="SemiBold"
Text="{Binding Path=PublishDate.LocalDateTime, StringFormat='{}{0:d MMM, HH:mm}'}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now the code behind:
Solution 1: this applies a new style when listboxitem is deselected. Not used anymore so the LB1_SelectionChanged event is not present in the XAML.
private void LB1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.RemovedItems.Count != 0)
{
foreach (var lbItem in e.RemovedItems)
{
//get reference to source listbox item. This was a pain.
int intDeselectedItem = LB1.Items.IndexOf(lbItem);
ListBoxItem lbi = (ListBoxItem)LB1.ItemContainerGenerator.ContainerFromIndex(intDeselectedItem);
/*apply style. Initially, instead of applying a style, I used mylistboxitem.Foreground = Brushes.Gray to set the text color.
Howver I noticed that if I scrolled the ListBox to the bottom, the text color would revert to the XAML default style in my XAML.
I assume this is because of refreshes / redraws (whichever the correct term). Applying a new style resolved.*/
Style style = this.FindResource("DeselectedTemplate") as Style;
lbi.Style = style;
}
}
}
Solution 2: The one I went with. Occurs on SelectedItem = true, same effect as your first suggestion.
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
TextBlock tb = e.Source as TextBlock;
tb.Foreground = Brushes.Gray;
}

Is there a way to prevent or recover from ListViewItems becoming MS.Internal.NamedObject

I have a UserControl that is a ListView with a Canvas as the ItemsPanel. The ItemsSource of the ListView is bound to a CollectionViewSource with it's Source property bound to an ObservableCollection< DeviceItem >. DeviceItem is a custom class that, among other things, holds the X/Y coordinates of the ListViewItem/DeviceItem which gets serialized when the user wants to save their work. On PreviewMouseDown and PreviewTouchDown I check the ListViewItem that's being clicked/touched to make sure that the content of the ListViewItem is a DeviceItem so that as the user moved it around the screen the software can updates the coordinates on the DeviceItem. This works 99% of the time but I run into a problem (sometimes) after the user removes items from the collection and then adds new items. After removing/adding, when the user clicks/touches the ListViewItem it's Content is typeof MS.Internal.NamedObject and in that case I can't act on the item. I'm sure it's worth mentioning that the user is adding/removing from a separate control in another window that is bound to the same collection in our data model (ObservableCollection< DeviceItem >).
Currently the user has to close and reopen the software when this happens. I'm trying to find a way to recover without restarting the software.
<UserControl.Resources>
<Style x:Key="CanvasStyle" TargetType="{x:Type Canvas}">
<EventSetter Event="Loaded" Handler="Canvas_Loaded"/>
</Style>
<CollectionViewSource Source="{Binding DiagramCollection}" x:Key="radioPacksDataView" />
</UserControl.Resources>
<Grid>
<ListView Name="listBoxDevices"
Background="Transparent"
BorderThickness="0"
Stylus.IsPressAndHoldEnabled ="False"
ItemsSource="{Binding Source={StaticResource radioPacksDataView}}"
PreviewMouseMove="ListBox_PreviewMouseMove"
PreviewMouseDown="ListBox_PreviewMouseDown"
PreviewMouseUp="ListBox_PreviewMouseUp"
PreviewTouchDown="ListBox_PreviewTouchDown"
PreviewTouchMove="ListBox_PreviewTouchMove"
PreviewTouchUp="ListBox_PreviewTouchUp"
SnapsToDevicePixels="True"
IsHitTestVisible="{Binding AccessRights, ConverterParameter=Unlocked, Converter={StaticResource enumBooleanConverter}, Source={x:Static appData:Globals.CurrentUser}}"
VirtualizingPanel.IsVirtualizing="False"
IsSynchronizedWithCurrentItem="False">
<ListView.Style>
<Style>
<Setter Property="ItemsControl.ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas Style="{DynamicResource CanvasStyle}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=window, Path=IconStyle}" Value="0">
<Setter Property="ListView.ItemContainerStyle" Value="{DynamicResource MultiDeviceItemContainerStyle}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=window, Path=IconStyle}" Value="1">
<Setter Property="ListView.ItemContainerStyle" Value="{DynamicResource MultiDeviceItemContainerStyleV2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Style>
<ListView.LayoutTransform>
<ScaleTransform CenterX="0"
CenterY="0"
ScaleX="{Binding ZoomScale}"
ScaleY="{Binding ZoomScale}"/>
</ListView.LayoutTransform>
</ListView>
</Grid>
And then in code behind
private void ListBox_PreviewMouseDown(object sender, MouseEventArgs e)
{
if (m_selectedListViewItem == null)
{
m_selectedListViewItem = ItemsControl.ContainerFromElement((ListBox)sender, e.OriginalSource as DependencyObject) as ListViewItem;
//this is the section that fails after removing/adding items, object is typeof(MS.Internal.NamedObject)
if (m_selectedListViewItem.Content.GetType().IsSubclassOf(typeof(DeviceItem)))
{
m_selectedDeviceItem = m_selectedListViewItem.Content as DeviceItem;
}
}
}

Change style (in ResourceDictionary) from code

I have this ResourceDictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MainMenuLabelStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Foreground" Value="White"/>
<Setter Property= "FontSize" Value="18"/>
<Setter Property= "FontFamily" Value="Arial"/>
</Trigger>
</Style.Triggers>
</Style>
If I want change the font size or color, what can I do ? This code doesn't work .
Application.Current.Resources("MainMenuLabelStyle") = 25
This is the xaml
<TextBlock Text="Uscita" Grid.Row="1" Grid.Column="1" TextAlignment="Left" Margin="4" TextWrapping="Wrap" Style="{DynamicResource MainMenuLabelStyle}">
Just before a style is used for the first time in a WPF application, it is sealed for performance reasons and it is not possible to modify it anymore. You can read it on MSDN.
So, if you want to change your style, you have to options. The first one (the easiest one) is to declare as many styles as you need and put them in your ResourceDictionary.
The second solution is to consider that a Setter is a DependencyObject, so you can bind its dependency properties. In this case your style will become:
<Style x:Key="MainMenuLabelStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag.Foreground, TargetNullValue=Red, FallbackValue=Red}" />
<Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag.FontSize, TargetNullValue=18, FallbackValue=18}" />
<Setter Property="FontFamily" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag.FontFamily, TargetNullValue=Arial, FallbackValue=Arial}" />
</Trigger>
</Style.Triggers>
</Style>
Now you can change the style just by setting the Tag property of every TextBlock control:
<StackPanel>
<TextBlock Text="Uscita" TextAlignment="Left" Margin="4" TextWrapping="Wrap" Style="{DynamicResource MainMenuLabelStyle}" />
<TextBlock Text="Uscita" TextAlignment="Left" Margin="4" TextWrapping="Wrap" Style="{DynamicResource MainMenuLabelStyle}">
<TextBlock.Tag>
<local:StyleConfig FontSize="50" FontFamily="Tahoma" Foreground="Orange" />
</TextBlock.Tag>
</TextBlock>
</StackPanel>
As you can see the first TextBlock will use the style as it was declared. On the other side, the second TextBlock will use a modified version of the original style.
Of course, in order to make this option work correctly, you must create a class (StyleConfig in my sample), which could be something like this:
public class StyleConfig
{
public string Foreground { get; set; }
public string FontSize { get; set; }
public string FontFamily { get; set; }
}
I hope it can help you.
In your code:
Application.Current.Resources("MainMenuLabelStyle") = 25
1) Wrong syntax. Application.Current.Resources["MainMenuLabelStyle"]
2) Application.Current.Resources["MainMenuLabelStyle"] this code will return object with type Style, not style property Font Size.
You can create new Style and replace it in ResourceDictionary.

Conditional styling of an element in XAML

I am building a Windows phone 8 app that has a view model property of:
public bool IsReply {get; set;}
In my xaml code, I would like to distinguish two cases:
IsReply=True
<Grid Margin="0,0,0,0">
...
</Grid>
IsReply=False
<Grid Margin="40,0,0,0">
...
</Grid>
Basically, I would like to style the Grid element depending on the value of IsReply. I know that in WPF Style.Triggers exists, but apparently not in WP.
The solution I have right now is to have a duplicate copy of the entire grid code and set the visibility of each to a data converter. However, I feel this should be simpler to do.
The easiest way is to use a Style with Triggers:
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Margin" Value="40 0 0 0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsReply}" Value="True">
<Setter Property="Margin" Value="0 0 0 0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
You can bind the margin of the grid in your MVVM
<Grid Margin="{Binding margin}">
...
</Grid>
In your model
if(IsReply)
margin = new Thickness("0,0,0,0");
else
margin = new Thickness("40,0,0,0");
No need to create separate grids.
You can use DataTrigger, but you have to add these two references (right click on References in your project and AddReference/Assemblies/Extensions/ ... ).
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<Grid
Margin="0">
<i:Interaction.Triggers>
<ei:DataTrigger
Binding="{Binding Path=IsReply}"
Value="True">
<ei:ChangePropertyAction
PropertyName="Margin"
Value="0" />
</ei:DataTrigger>
<ei:DataTrigger
Binding="{Binding Path=IsReply}"
Value="False">
<ei:ChangePropertyAction
PropertyName="Margin"
Value="40,0,0,0" />
</ei:DataTrigger>
</i:Interaction.Triggers>
</Grid>

ToggleButton change background when pressed (but only once)

When a button gets pressed the background (Rectangle Fill) of the button changes. So the user can see what buttons have been pressed and what not.
Problem:
I use a trigger and a Togglebutton to perform the "IsChecked" to change the background.
But the background change may only happens 1 time.
For example:
Button Background = black --> PRESS --> Button Background = blue
But when i press the button again the Button BackGround changes back to black (since its a ToggleButton).
How can i make sure the background only changes 1 time?
EDIT: The button must remain enabled, because a user gives in a reason when they press the button. Meaning if they pick the wrong reason they are able to change it.
<Style x:Key="ButtonStyleReg" TargetType="{x:Type myClasses:RegButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="registrationButton">
<Rectangle Name="rectangleBtn" Fill="#FF89959A" Height="Auto" RadiusY="15" RadiusX="15" Stroke="White" Width="Auto"/>
<TextBlock x:Name="reason" TextWrapping="Wrap"
Text="{Binding Reason, StringFormat=\{0\}}"
HorizontalAlignment="Center" Margin="0,7.5,0,0" Height="Auto"
VerticalAlignment="Top" FontWeight="Bold" >
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<!--<Trigger Property="IsDefaulted" Value="True"/>-->
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="rectangleBtn" Property="Fill" Value="blue" />
</Trigger>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="10.667"/>
Listbox that implements the style:
<ListBox x:Name="lbRegistration" ItemsSource="{Binding RegBtns, ElementName=Window}" Background="{x:Null}"
BorderBrush="{x:Null}" Grid.Column="1"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Disabled" Height="75">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegistration}"
Click="RegistrationButton_Click"
Title="{Binding Title}"
Oorzaak="{Binding Oorzaak}"
DuurStilstand="{Binding DuurStilstand,
Converter={StaticResource DateTimeConverter}}"
BeginStilstand="{Binding BeginStilstand}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Best Regards,
Pete
Very simple would be if you can access the rectangle from code behind:
rectangleBtn.Fill = Brushes.Blue;
If you can't access it - make yourself two styles.
The one that is the original style, the other one is the Blue Style which shall be applied when the user clicks.
In the code behind, on event Click="RegistrationButton_Click"
Set the Style to the BlueStyle.
RegistrationButton.Style = this.FindResource("ButtonStyleRegistration") as Style;
Since you always want it blue, this code is enough as it is. It will always make it Blue for you.
The first time, and any other time.
That way you achieve your requirement and the style will change only once.
When the window is loaded, it will load into the original style (the first style).
So put in your XAML the style "Black" and in the code behind as shown above.
Then this must be removed:
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="rectangleBtn" Property="Fill" Value="blue" />
</Trigger>
Then this:
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegistration}"
Click="RegistrationButton_Click"
Shall be:
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegBlack}"
Click="RegistrationButton_Click"
That is all.
If you're using an MVVM approach I would recommend binding the background and the Click command to members in the ViewModel. The first time the button is clicked it sets a flag and changes the background color. The next time the button is clicked, if the flag is set, the command returns without changing the background.
XAML:
<ToggleButton Background="{Binding MyBackground}" Command="{Binding OnClickCmd}"/>
ViewModel
public class ViewModel : INotifyPropertyChanged
{
public Brush MyBackground
{
get { return background_; }
set {
background_ = value;
PropertyChanged(this, new PropertyChangedEventArg("MyBackground");
}
}
public ICommand OnClickCmd
{
get {
return new DelegateCommand(()=>{ // DelegateCommand implements ICommand
if(!isBackgroundSet) {
background = Brushes.Red;
isBackgroundSet_ = true;
}
});
}
}
private Brush background_;
private bool isBackgroundSet_;
private event PropertyChangedEventHandler PropertyChagned;
}

Categories