Set checkbox style template label programmaticaly WPF - c#

I created a style for a checkbox in WPF and created an array of those checkboxes programmaticaly. The style is as follows
<Style x:Key="deviceZoom" TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel x:Name="dockPanel">
<Canvas Width="24.15" Height="23">
<Image Source="/Resources/Icons/deviceUnselectedDiscrete.png" x:Name="DeviceImage" Width="12" Height="19" Canvas.Top="4"/>
<Border x:Name="borderDevice"
CornerRadius="5"
Width="20"
Height="10"
Background="#222528"
BorderThickness="0"
Canvas.Top="1"
Canvas.Left="4.15">
<TextBlock x:Name="numBoards" HorizontalAlignment="Center" VerticalAlignment="Center" Padding=".1" FontSize="8" Foreground="White" Text="99"/>
</Border>
</Canvas>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And then I create some checkboxes like so and add to the root canvas
Style style = canvas.FindResource("deviceZoom") as Style;
var deviceCheckbox = new CheckBox();
canvas.Children.Add(deviceCheckbox);
deviceCheckbox.Style = style;
//Here I would like to set the label text
Now I would like to set from code behind a value to the label numBoards every time I have new data, but I don't know how. I tried using Dynamic Properties but didn't manage to set them well since the checkbox is created programmaticaly, and tried with binding but without success

CheckBox has Content property. Binding TextBlock.Text in template to owner Content via TemplateBinding.
<Style x:Key="deviceZoom" TargetType="{x:Type CheckBox}">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel x:Name="dockPanel">
<Canvas Width="24.15" Height="23">
<Image Source="/Resources/Icons/deviceUnselectedDiscrete.png" x:Name="DeviceImage" Width="12" Height="19" Canvas.Top="4"/>
<Border x:Name="borderDevice"
CornerRadius="5"
Width="20"
Height="10"
Background="#222528"
BorderThickness="0"
Canvas.Top="1"
Canvas.Left="4.15">
<TextBlock x:Name="numBoards"
HorizontalAlignment="Center" VerticalAlignment="Center"
Padding=".1" FontSize="8" Foreground="White"
Text="{TemplateBinding Content}"/>
</Border>
</Canvas>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then you can assign Content and it will be displayed in TextBlock:
deviceCheckbox.Content = "I am deviceCheckbox";

first, add UserControl. and add new property. it bind numBoards. XAML is ..
<UserControl x:Class="yourproject.myCheckBox"
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:yourproject"
mc:Ignorable="d" x:Name="rootCtrl"
d:DesignHeight="450" d:DesignWidth="800">
<Canvas>
<CheckBox DataContext="{Binding ElementName=rootCtrl}" >
<CheckBox.Template>
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel x:Name="dockPanel">
<Canvas Width="24.15" Height="23">
<Image Source="/Resources/Icons/deviceUnselectedDiscrete.png" x:Name="DeviceImage" Width="12" Height="19" Canvas.Top="4"/>
<Border x:Name="borderDevice"
CornerRadius="5"
Width="20"
Height="10"
Background="#222528"
BorderThickness="0"
Canvas.Top="1"
Canvas.Left="4.15">
<TextBlock x:Name="numBoards" HorizontalAlignment="Center" VerticalAlignment="Center" Padding=".1" FontSize="8" Foreground="White" Text="{Binding NumBoards}"/>
</Border>
</Canvas>
</DockPanel>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
</Canvas>
</UserControl>
Code is ..
public partial class myCheckBox : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
private string _NumBoards = "77";
public string NumBoards
{
get
{
return _NumBoards;
}
set
{
_NumBoards = value;
OnPropertyChanged("NumBoards");
}
}
public myCheckBox()
{
InitializeComponent();
}
}
and use myCheckBox control
var deviceCheckbox = new myCheckBox();
deviceCheckbox.NumBoards = "20";
canvas.Children.Add(deviceCheckbox);

Related

Sending Tab during the click event of a button inside the header of the tabitem

I am trying to delete the tab on click of a button(TabCloseButton) inside the tabitem header. but i can't get the tab as parent too. Can anyone help me find out how to pass the tab to the click method. Any code sample will be helpful.
<TabControl Name="ConnectionsTab" BorderThickness="0" Background="White">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Background="White">
<Border Name="Border" BorderBrush="#1b9ed2" Margin="6,0,12,0" Background="White">
<ContentPresenter Height="30" x:Name="ContentSite" ContentSource="Header" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="5,15,5,-5">
</ContentPresenter>
</Border>
<Button Background="Wheat" BorderBrush="Transparent" Name="TabCloseButton" Click="TabCloseButton_Click" HorizontalAlignment="Right" VerticalAlignment="Bottom" ToolTip="Close" HorizontalContentAlignment="Right" Padding="0">
<materialDesign:PackIcon Kind="Close" Foreground="Gray" HorizontalAlignment="Right"/>
</Button>
</Grid>
<ControlTemplate.Triggers>
...............
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="12"/>
</Style>
</TabControl.Resources>
<TabItem Header="Connections" IsSelected="True" TabIndex="0">
<TabItem.Content>
<Grid>
<TextBlock Name="errorMessage" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Gray" Visibility="Hidden"></TextBlock>
<Grid Name="MainConnectionTab"/>
</Grid>
</TabItem.Content>
</TabItem>
<TabItem Header="machine1"></TabItem>
<TabItem Header="machine2"></TabItem>
</TabControl>
You could use a helper method that uses the VisualTreeHelper to find the parent TabItem in the visual tree:
private void TabCloseButton_Click(object sender, RoutedEventArgs e)
{
Button tabCloseButton = (Button)sender;
TabItem parentTab = FindParent<TabItem>(tabCloseButton);
if (parentTab != null)
ConnectionsTab.Items.Remove(parentTab);
}
private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null)
return null;
T parentT = parent as T;
return parentT ?? FindParent<T>(parent);
}

How to change resource template element's property using only XAML?

The main idea is to have a button with default icon "yes.png" and text in it "Accept", but have a possibilty to change these two properties using only XAML(at the designing process, without compiling).
Current XAML window which has an area at the bottom with only two buttons:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<Style x:Key="tb1" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="1" BorderBrush="#000" Padding="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="Files/Icons/no.png" Margin="10,0,0,0" Height="16" Width="16"></Image>
<TextBlock Grid.Column="1" Margin="10" VerticalAlignment="Center">Cancel</TextBlock>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0,10,10,10"></Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Border BorderThickness="0, 1, 0, 0" BorderBrush="#e7e7e7" HorizontalAlignment="Stretch" Padding="0,0,0,0" VerticalAlignment="Bottom" Height="61">
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="b_Accept" Style="{StaticResource tb1}"></Button> <!-- How to change an icon to "yes.png" and TextBlock's content to "Accept"? -->
<Button x:Name="b_Cancel" Style="{StaticResource tb1}"></Button>
</StackPanel>
</Border>
</Grid>
</Window>
Result:
Please,
How is it possible to change second button's icon to "no.png"(Source property) and TextBlock's text(Content) to "Cancel"(only using XAML and not User Control)?
What would be the very right way(the easiest?)? For example, in this post we might use DataTemplate, but might be that's not that we want to because DataTemplate changes the whole element, while we need only one property.
Although, I am right that there are only dependency property(C#) available for that purpose which expects compiling?
Thank you
You can create your custom Button class or an Attached Property to extend the Button:
public class IconControl : DependencyObject
{
#region IconUri attached property
public static readonly DependencyProperty IconUriProperty = DependencyProperty.RegisterAttached(
"IconUri", typeof(ImageSource), typeof(IconControl), new PropertyMetadata(default(ImageSource)));
public static void SetIconUri([NotNull] DependencyObject attachingElement, ImageSource value)
{
attachingElement.SetValue(IconControl.IconUriProperty, value);
}
public static ImageSource GetIconUri([NotNull] DependencyObject attachingElement) => (ImageSource) attachingElement.GetValue(IconControl.IconUriProperty);
#endregion
#region Label attached property
public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached(
"Label", typeof(String), typeof(IconControl), new PropertyMetadata(default(String)));
public static void SetLabel([NotNull] DependencyObject attachingElement, String value)
{
attachingElement.SetValue(IconControl.LabelProperty, value);
}
public static String GetLabel([NotNull] DependencyObject attachingElement) => (String) attachingElement.GetValue(IconControl.LabelProperty);
#endregion
}
Modified Style for the Button:
<Style x:Key="IconButtonStyle"
TargetType="{x:Type Button}">
<!-- Set the default values -->
<Setter Property="IconControl.IconUri" Value="/Files/Icons/no.png"/>
<Setter Property="IconControl.Label" Value="Cancel"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="1"
BorderBrush="#000"
Padding="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.IconUri)}"
Margin="10,0,0,0"
Height="16"
Width="16" />
<TextBlock Grid.Column="1"
Margin="10"
VerticalAlignment="Center"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(IconControl.Label)}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Margin"
Value="0,10,10,10"></Setter>
</Style>
Usage:
<!-- Override the default content -->
<Button Style="{StaticResource IconButtonStyle}"
IconControl.IconUri="/Files/Icons/yes.png"
IconControl.Label="Accept" />

How to bind text to my custom XAML control?

I want to bind a DependencyProperty to my TextBox, what I need to do is to create a control that allows me to write a text in its property "Letter" and sets it as the text of the TextBlock defined in the template. I've never done this before so I'm not sure of how to do it.
Here's the .xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:My_App">
<Style TargetType="local:GameLetter" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GameLetter">
<Grid>
<Image Source="Assets/imgs/letter_key.png"/>
<Viewbox Margin="10,0">
<TextBlock x:Name="textBlock" FontFamily="Assets/fonts/avenirnext.ttf#Avenir Next" Text="{Binding Letter}" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here's the .cs:
public sealed class GameLetter : Control
{
public GameLetter()
{
this.DefaultStyleKey = typeof(GameLetter);
}
public static readonly DependencyProperty LetterProperty =
DependencyProperty.Register("Letter", typeof(string), typeof(GameLetter), new PropertyMetadata(null));
public string Letter
{
get { return (string)GetValue(LetterProperty); }
set { SetValue(LetterProperty, value); }
}
}
You're close. The problem with your binding is that it'll search the Letter property on your datacontext, not on your control. You can fix that by using a TemplateBinding:
<Style TargetType="local:GameLetter" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:GameLetter">
<Grid>
<Image Source="Assets/imgs/letter_key.png"/>
<Viewbox Margin="10,0">
<TextBlock x:Name="textBlock" FontFamily="Assets/fonts/avenirnext.ttf#Avenir Next" Text="{TemplateBinding Letter}" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Custom control - Listview with no predefined content WPF/c#

I used for the first time a custom Control (wpf). Here is what I want:
I want a Custom ListView with Custom ListViewItem (the challenge is I don’t know what’s on the “Form”, I just know it’s a Panel - I call "Form" what's on the ListViewItem ).
I have a CustomListView and a CustomListViewItem :
EDIT : CustomListView.cs
public class CustomListView : ItemsControl
{
public static readonly DependencyProperty ListContentProperty = DependencyProperty.Register("ListContent", typeof(IList), typeof(CustomListView), new PropertyMetadata());
public IList ListContent
{
get { return (IList)GetValue(ListContentProperty); }
set { SetValue(ListContentProperty, value); }
}
public CustomListView(ContentControl contentControl, IList list)
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomListView), new FrameworkPropertyMetadata(typeof(CustomListView)));
DataContext = list;
ItemsSource = list;
CustomListViewItem customListViewItem = new CustomListViewItem();
customListViewItem.Content = contentControl;
string xamlTemplate = XamlWriter.Save(customListViewItem);
string template =
"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
xamlTemplate +
"</DataTemplate>";
ItemTemplate = (DataTemplate)XamlReader.Parse(template);
SetValue(TemplateContentProperty, contentControl);
}
}
EDIT : CustomListViewItem .cs
public class CustomListViewItem : ContentControl
{
public static readonly DependencyProperty MyEventProperty = DependencyProperty.Register("MyEvent", typeof(EventHandler), typeof(CustomListViewItem));
public static readonly DependencyProperty ListContentItemProperty = DependencyProperty.Register("ListContentItem", typeof(IList), typeof(CustomListViewItem), new PropertyMetadata());
public IList ListContentItem
{
get { return (IList)GetValue(ListContentItemProperty); }
set { SetValue(ListContentItemProperty, value); }
}
public EventHandler MyEvent
{
get { return (EventHandler)GetValue(MyEventProperty); }
set { SetValue(MyEventProperty, value); }
}
public CustomListViewItem()
{
DefaultStyleKey = typeof(CustomListViewItem);
}
//Some method for the Event on my button
The DataContext of the CustomListView is an ObservableCollection. When I create the “Form” directly on my CustomListViewItem, everything is perfect. I can sort with my button, add a new empty Form…
Now here is my problem.
Let’s say we have a class Person (with only a name) who implements INotifyPropertyChanged. We create some “Person” and add them to an ObservableCollection. On a new xaml element, we create a Template (PersonEditor) the “Form”, with some Binding.
What I want on the MainWindows is something like that:
CustomListView customListView = new CustomListView(new PersonEditor(), _person);
myContentControl.Content = customListView;
Where _person is the ObservableCollection. We give the Template of the Form to the CustomListViewItem and add it to a content of a ContentControl
EDIT : Generics.xaml :
<Style x:Key="{x:Type customControl:CustomListView}" TargetType="customControl:CustomListView" BasedOn="{StaticResource {x:Type ItemsControl}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type customControl:CustomListView}">
<Border>
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type customControl:CustomListViewItem}" TargetType="customControl:CustomListViewItem" BasedOn="{StaticResource {x:Type ContentControl}}">
<Setter Property="ListContentItem">
<Setter.Value>
<Binding Path="ListContent" RelativeSource="{RelativeSource FindAncestor,AncestorType=customControl:CustomListView}"></Binding>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="customControl:CustomListViewItem">
<Border Background="White" x:Name="borderSelect" Padding="0" Width="Auto" Height="Auto">
<DockPanel Width="Auto" Height="Auto" VerticalAlignment="Stretch">
<ContentPresenter/>
<StackPanel Orientation="Horizontal">
<StackPanel SnapsToDevicePixels="true" Orientation="Vertical" Margin="0">
<StackPanel SnapsToDevicePixels="true" Orientation="Horizontal" Margin="0">
<Button SnapsToDevicePixels="true" Style="{StaticResource SquareCorner}" Opacity="0.0" Margin="0 7 0 0" Height="30" Width="12" VerticalAlignment="top" HorizontalAlignment="Right" Content="x" Padding="0" x:Name="DeleteButton" Command="{TemplateBinding MyEvent}"/>
<StackPanel SnapsToDevicePixels="true" Orientation="Vertical">
<Button Style="{StaticResource RoundUpCorner}" Opacity="0.0" Margin="0 7 0 0" Height="15" Width="15" VerticalAlignment="top" HorizontalAlignment="Right" Content="^" Padding="0 0 0 5" x:Name="UpButton" Command="{TemplateBinding MyEvent}"/>
<Button Style="{StaticResource RoundDownCorner}" Opacity="0.0" Height="15" Width="15" VerticalAlignment="top" HorizontalAlignment="Right" Content="v" Padding="0" x:Name="DownButton" Command="{TemplateBinding MyEvent}"/>
</StackPanel>
</StackPanel>
</StackPanel>
<DockPanel VerticalAlignment="Stretch">
<Button Style="{StaticResource SquareLittleCorner}" DockPanel.Dock="Top" Opacity="0.0" Height="15" Width="15" VerticalAlignment="top" HorizontalAlignment="Right" Margin="1 0 0 0" Content="+" Padding="0" x:Name="AddUpButton" Command="{TemplateBinding MyEvent}"/>
<Button Style="{StaticResource SquareLittleCorner}" DockPanel.Dock="Bottom" Opacity="0.0" Height="15" Width="15" VerticalAlignment="bottom" HorizontalAlignment="Right" Margin="1 0 0 0" Content="+" Padding="0" x:Name="AddButton" Command="{TemplateBinding MyEvent}"/>
</DockPanel>
</StackPanel>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The result is I only have one element that has the good Template, the other ones are created but empty.
I think the problem comes from the binding. But I don’t know what to do. I tried to create a new “Form” with xamlReader/xamlLoad (How can you clone a WPF object?) but with the binding again it’s not good. I also tried to clone the xaml but again, no binding and no event on button.
I don’t know what else I can do to solve this problem ? It’s my first time with a custom control so if I made a mistake (anything) just share please.
EDIT
I think my custom is better now, I follow the idea of the DataTemplate and ContentControl mix with xamlReader/xamlLoad. The Binding is good (same for Event). But, why when I used it before (like a Content not a Template) the Binding wasn't good ? And I don't know if xamlReader/xamlLoad is a good way to do that (I mean it looks more like some cheat).

Binding RadioButton.IsChecked with Listbox.SelectedItem

My View is clickable like a radiobutton with about 7 other of these radiobuttons, but my listbox is not updating it's selected property unless I click outside of my radiobutton.
Basically I have a AbstractTask as my base. I have 7 child classes. I want to be able to select one of these AbstractTasks. That's all i'm after. So in my main window i have this.
<Window x:Class="AdvancedTaskAssigner.View.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:AdvancedTaskAssigner.View"
Title="MainWindowView" Height="300" Width="300" SizeToContent="Height">
<DockPanel>
<TextBlock Text="TextBlock" DockPanel.Dock="Top" />
<TextBlock Text="{Binding ElementName=listTasks, Path=SelectedItem.Name}" DockPanel.Dock="Top" />
<ListBox x:Name="listTasks" ItemsSource="{Binding Tasks}" HorizontalContentAlignment="Stretch" SelectedItem="{Binding IsSelected}">
<ListBox.ItemTemplate>
<DataTemplate>
<v:AbstractTaskView />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Window>
since this is a library and not a application I had to put this in the Constructor of MainWindowView
MainWindowView.xaml.cs
public MainWindowView()
{
InitializeComponent();
var atvm = new ViewModel.MainWindowViewModel();
atvm.LoadTasks();
this.DataContext = atvm;
}
MainWindowViewModel.cs
class MainWindowViewModel
{
internal void LoadTasks()
{
var assembly = Assembly.GetAssembly(typeof(AbstractTask)).GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractTask)));
Type[] typelist = GetTypesInNamespace(Assembly.GetAssembly(typeof(AbstractTask)), typeof(AbstractTask));
foreach (Type t in typelist)
{
if(!t.IsAbstract && t.BaseType.Equals(typeof(AbstractTask)))
{
tasks.Add(new AbstractTaskViewModel(t));
}
}
}
private Type[] GetTypesInNamespace(Assembly assembly, Type baseClass)
{
return assembly.GetTypes().Where(t => t.IsSubclassOf(baseClass)).ToArray();
}
private ObservableCollection<AbstractTaskViewModel> tasks = new ObservableCollection<AbstractTaskViewModel>();
public ObservableCollection<AbstractTaskViewModel> Tasks
{
get { return tasks; }
}
}
AbstractTaskViewModel.cs
public class AbstractTaskViewModel
{
public AbstractTaskViewModel(Type task)
{
if (!task.IsSubclassOf(typeof(AbstractTask)))
{
throw new NotSupportedException(string.Format("{0} is not a subclass of AbstractTask", task.Name));
}
Task = task;
}
public string Description
{
get
{
return GetCustomAttribute(0);
}
}
public string Name
{
get
{
return GetCustomAttribute(1);
}
}
public bool IsSelected{get;set;}
private string GetCustomAttribute(int index)
{
var descriptions = (DescriptionAttribute[])Task.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (descriptions.Length == 0)
{
return null;
}
return descriptions[index].Description;
}
protected readonly Type Task;
}
AbstractTaskView.xaml
<RadioButton
x:Class="AdvancedTaskAssigner.View.AbstractTaskView"
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"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" GroupName="AbstractTasks" Background="Transparent" IsChecked="{Binding IsSelected, Mode=TwoWay}">
<RadioButton.Template>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Grid>
<Border x:Name="MyHead" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Background="LightGray" Margin="20,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Panel.ZIndex="2">
<TextBlock Text="{Binding Name}" Margin="5,2" MinWidth="50" />
</Border>
<Border x:Name="Myoooo" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Background="Transparent" Margin="0,10,0,0" Panel.ZIndex="1">
<TextBlock Text="{Binding Description}" Margin="5,15,5,2" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MyHead" Property="Background" Value="LightGreen" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
this is what i am getting..
I want the green border to be the selected item. not what the Listbox's Selected item is. The bottom text box is the name of the selected item.
There are some issues related to binding IsChecked property of RadioButton. You can read about it here or here. You can apply the solution presented in the first link using your AbstractTaskView instead of RadioButton. Replace your listbox in MainWindowView with the code:
<ListBox x:Name="listTasks" ItemsSource="{Binding Tasks}" HorizontalContentAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<v:AbstractTaskView Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
You have to also remove the folowing part of code from AbstractTaskView:
IsChecked="{Binding IsSelected, Mode=TwoWay}"
I hope you don't need IsSelected property of AbstractTaskViewModel to be set. But if you do, you can set it for example in Checked event handler in AbstractTaskView code behind (I know it's not pretty solution).
I see you're binding the IsSelected (boolean) to the SelectedItem (object)

Categories