Radio checked function with wpf MVVM - c#

I was struggling to trigger checked function in WPF, but when it comes to code-behind concept it is okay, but I want to get checked button value with MVVM theory. So do you guys have any idea about this? and in the below, there is tried code with code behind theory.
<DataTemplate>
<dc:RadioButton GroupName="DemoRadios1"
Margin="0,0,15,0"
IsEnabled="{Binding RadioIsEnabled}"
IsReadOnly="{Binding RadioIsReadOnly}"
InnerCheckerVisibilityWhenReadOnly="{Binding RadioInnerCheckerVisibilityWhenReadOnly}"
InnerCheckerVerticalAlignment="{Binding RadioInnerCheckerVerticalAlignment}"
IsChecked="{Binding IsChecked}"
Content="{Binding OverridedSettingValueName}"
Checked="RadioButton_Checked"/>
</DataTemplate>
#Code behind function
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
// ... Get RadioButton reference.
var button = sender as RadioButton;
// ... Display button content as title.
var Title = button.Content.ToString();
}

It looks like maybe you have a collection of things you're working with.
RadioButton has a command property, so you could potentially bind a command and commandparameter if this code must be in the window viewmodel.
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<StackPanel>
<TextBlock Text="{Binding RowName}"/>
<ItemsControl ItemsSource="{Binding Rows}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Name}"
IsChecked="{Binding IsChecked}"
Command="{Binding DataContext.CheckedCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
GroupName="DemoRadios1"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Window>
My viewmodel:
public class MainWindowViewModel : BindableBase
{
public DelegateCommand<RowVM> CheckedCommand { get; private set; }
public ObservableCollection<RowVM> Rows{ get; set; } = new ObservableCollection<RowVM>(
new List<RowVM>
{
new RowVM{Name="Andrew"},
new RowVM{Name="Bill"},
new RowVM{Name="Carol"},
}
);
private string rowName;
public string RowName
{
get => rowName;
set { SetProperty(ref rowName, value); }
}
public MainWindowViewModel()
{
CheckedCommand = new DelegateCommand<RowVM>((row) =>
{
if(!row.IsChecked)
{
return;
}
RowName = row.Name;
});
}
My RowVM lacks any raising of property changed.
public class RowVM : BindableBase
{
public string Name { get; set; }
public bool IsChecked { get; set; } = false;
}
I'm guessing this datatemplate is used for a collection so there will be an itemscontrol with an itemssource bound to a collection of row viewmodels.
This is somewhat simpler if you can instead have code in the viewmodel for a row.
You already bound IsChecked.
You can therefore just put some code in the set accessor if that bound IsChecked property of your viewmodel:
public class RowViewModel : BindableBase
{
private bool isChecked;
public bool IsChecked
{
get => isChecked;
set
{
isChecked = value;
DoStuff(value);
RaisePropertyChanged();
}
}

Related

Combobox Itemsource Binding does not work

I'm trying to fill my Combobox ItemsSource using Binding in Xaml with a collection of data ObservableCollection but I always get the Combobox ItemsSource null .
WPF UserControl Cs Code : ( Update the code )
public ObservableCollection<User> users { get; set; }
public partial class MainWindow : Window
{
InitializeComponent();
User user1 = new User("Mariah", 15);
User user2 = new User("John", 19 );
users = new ObservableCollections<User>();
users.Add(user1);
users.Add(user2);
this.DataContext = this;
Console.WriteLine(ComboBoxUsers.Items.Count); // always 0
Console.WriteLine(ComboBoxUsers.ItemsSource); // always null
}
WPF UserControl Xaml Code : ( Updated my code )
<ComboBox SelectedIndex = "0" x:Name="ComboBoxUsers" ItemsSource="{Binding users, UpdateSourceTrigger=PropertyChanged}" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image IsEnabled="False" Source="{Binding Image}"/>
<TextBlock x:Name="textblock" IsEnabled="False" Text="{Binding Name} />
</StackPanel>
<DataTemplate.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnable" Value="{Binding IsEnable}"/>
</Style>
</DataTemplate.Resources>
</DataTemplate>
</ComboBox.ItemTemplate>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Setter
Property="Visibility"
Value="{Binding IsHidden}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Class User
public class User
{
public string Name { get; set; }
public int Age { get; set; }
public User(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
What is the source of this problem?
Discarding unnecessary (which is not relevant to the question or has syntax errors), your example with a little formatting works fine.
XAML:
<ComboBox x:Name="ComboBoxUsers"
ItemsSource="{Binding Users}"
FontFamily="Arial"
FontSize="11"
Grid.Row="3"
Height="30"
Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock IsEnabled="False"
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Code-behind:
public class User
{
public string Name { get; }
public int Age { get; }
public User(string name, int age)
{
Name = name;
Age = age;
}
}
public partial class MainWindow : Window
{
public ObservableCollection<User> Users { get; }
public MainWindow()
{
InitializeComponent();
// Initialize collection with some items
Users = new ObservableCollection<User>
{
new User("Mariah", 15),
new User("John", 19)
};
DataContext = this;
}
}
Result:
Remarks:
Your
Console.WriteLine(ComboBoxUsers.Items.Count); // always 0
Console.WriteLine(ComboBoxUsers.ItemsSource); // always null
because you use Binding. You needn't access ItemsSource or Items.Count through ComboBox - you should use binded collection Users (e.g. Users.Count) to manipulate or get ComboBox content.
EDIT.
About SelectedItem. You should define for yourself, you want use Bindings or work with ComboBox directly.
Binding push you to NOT use ComboBox.SelectedItem/Index/Value whatever. Even not access ComboBoxUsers to get some data. Binding is closely related to, for example, the MVVM Pattern. If you decided to use Bindings - forget about accessing directly to ComboBox or it data properties SelectedItem/Index/Value or similar.
If you use Bindings - you should create a property (e.g. SelectedUser) for SelectedItem (same as you create property Users for your ItemsSource ) and bind to it:
XAML (introducing binding for SelectedItem property and SelectionChanged handler):
<ComboBox x:Name="ComboBoxUsers"
ItemsSource="{Binding Users}"
SelectedItem="{Binding SelectedUser}"
SelectionChanged="OnUserSelectionChanged"
FontFamily="Arial"
FontSize="11"
Grid.Row="3"
Height="30"
Margin="10,5,5,5">
</ComboBox>
Code-behind (introducing property SelectedUser and OnUserSelectionChanged handler):
public partial class MainWindow : Window
{
public ObservableCollection<User> Users { get; }
// Here would be stored your Binded selected item
public User SelectedUser { get; set; }
// And here is your handler when selection changed
private void OnUserSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// SelectedUser property stores selected in ComboBox item,
// so you can use it directly
_ = MessageBox.Show(SelectedUser.Name);
// Even if you wish to get directly - it is possible
// (thanks to #Clemens):
var selectedUser = (sender as ComboBox).SelectedItem as User;
var selectediIndex = (sender as ComboBox).SelectedIndex;
}
public MainWindow()
{
InitializeComponent();
Users = new ObservableCollection<User>
{
new User("Mariah", 15),
new User("John", 19)
};
DataContext = this;
}
}
Repeat same algorithm for each property you wish to Bind (e.g. SelectedIndex):
SelectedIndex="{Binding SelectedUserIndex}"
public int SelectedUserIndex { get; set; }
Result:
Decide for yourself, what you need. Nice modern Bindings or old boring (sender as ComboBox).SelectedItem.

How to properly bind Checkbox property

I am working on a wpf application and I am dealing with checkboxes now
The problem when I set the Ischecked property to "True" like this:
<CheckBox Visibility="{Binding checkVisibility}" IsChecked="true"
IsEnabled="True"></CheckBox>
I get my checkbox checked
But when I try to bind a booléan property that it's value is "true" i get my checkbox always unchecked
I can't see where is the proplem
this is my xaml
<CheckBox Visibility="{Binding checkVisibility}" IsChecked="{Binding Path=test,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" IsEnabled="True"></CheckBox>
this is my property
public bool _test = true;
public bool test {
get {
return _test;
}
set {
if (_test == value) {
return;
}
_test = value;
RaisePropertyChanged("test");
}
}
I want my checkbox to reflect my property value and vice versa but it's not the case as my checkbox is always unchecked
I am missing something?
Edit
Here is my VM:
namespace X{
public class MyViewModel :
{
public MyViewModel()
{
TestCheckbox();
}
#Region Properties
public bool _test1 = true;
public bool test1
{
get
{
return _test1;
}
set
{
if (_test1 == value)
{
return;
}
_test1 = value;
RaisePropertyChanged("test1");
}
}
ObservableCollection<Output> _output_List;
public ObservableCollection<Output> output_List
{
get { return _output_List; }
set
{
if (_output_List == value) return;
_output_List = value;
RaisePropertyChanged("output_List");
}
}
#EndRegion
#Region ButtonCommand
private RelayCommand _SetOutputPropertiesCommand;
public RelayCommand SetOutputPropertiesCommand => _SetOutputPropertiesCommand
?? (_SetOutputPropertiesCommand = new RelayCommand(
() =>
{
foreach (Output item in output_List)
{
item.myvalue=Test2;
}
}
}));
#EndRegion
#Region Method
public void TestCheckbox()
{
Console.Writeline(Test2);
}
#EndRegion
}
public class Output
{
public string label { get; set; }
public string type { get; set; }
public bool myvalue { get; set; }
public bool Test2 { get; set; }
[System.ComponentModel.DataAnnotations.Schema.NotMapped]
[JsonIgnore]
public string checkVisibility { get; set; }
}
}
My Xaml : my checkboxes are integrated in a DataGrid view
<DataGrid x:Name ="GridO" Style="{x:Null}"
ItemsSource= "{Binding output_List,UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False" CellStyle="{StaticResource Body_Content_DataGrid_Centering}"
Margin="5,0" IsReadOnly="True" SelectionMode="Single" RowHeight="50" Height="Auto">
<DataGrid.Columns>
<DataGridTextColumn Width="40*" Binding="{Binding label}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Input"></TextBlock>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTextColumn Width="40*" Binding="{Binding type}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text = "Type"></TextBlock>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridTemplateColumn Width="20*" >
<DataGridTemplateColumn.Header>
<TextBlock Text="Value" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="20,0,0,0" Visibility="{Binding checkVisibility }" IsChecked="{Binding Test2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsEnabled="True"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button x:Name="Valid_output" Cursor="Hand" Background="Transparent" Height="55" Width="140" Margin="0,0,20,0" Command="{Binding SetOutputPropertiesCommand}" >
The bind is Working with "Test2" and not working with "Test1" which not in the same class as Test2
NB: the Button command(which is in the same class as "Test1") is working well
My DataTemplate: are in the App.xaml
xmlns:v="clr-namespace:X.View"
xmlns:vm="clr-namespace:X"
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<v:MyWindow/>
I see the main problem in the DataGrid. You set ItemsSource to a collection, so for every row in the DataGrid the data source is one item in that collection. Not your MyViewModel.
This is the reason, why the Test2 is working - it is in the class which instances are in the collection.
You could try to add CheckBox to the window without DataGrid and bind the Test1 - it should work.
If you really want to use some property from your MyViewModel, you can, but it is not that easy. You have to have there something like:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNamespace"
<!--...something...-->
<DataGrid.Resources>
<local:BindingProxy x:Key="Proxy" Data="{Binding}" />
</DataGrid.Resources>
<!--...something...-->
And then your binding in the DataGrid will look like this:
IsChecked="{Binding Data.Test1, Source={StaticResource Proxy}}"
Of course I don't know the exact settings of your application so you will have to complete/change the code according to them.
I suggest you to add a ViewModelBase class, like that
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName =
null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Extends your ViewModel with this ViewModelBase class and implements your property
private bool myProperty;
public bool MyProperty { get; set; OnPropertyChanged(); }
Then you just have to bind on your property
<CheckBox IsChecked="{Binding MyProperty}"></CheckBox>
EDIT: To set your ViewModel as DataContext for your View you can set it from the code
MyView.DataContext = new MyViewModel();
or from the view, in the Window/User Control
<Window x:Class="MyApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApplication"
Title="MainWindow" Height="350" Width="525"
DataContext="local.MyViewModel">

Remove ListBoxItem from ViewModel

I develop CRUD app for WindowsPhone 8.1. I can add data to ObservableCollection collection and this data is displayed on ListBox. I use MVVM pattern.
Full repository https://github.com/OlegZarevych/CRUD_WP81
View :
<ListBox x:Name="Storage" ItemsSource="{Binding Path=Models, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="30" Width="450">
<TextBlock x:Name="nameblock" Text="{Binding Name}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And ViewModel class
public class ViewModel
{
public string NewName { get; set; }
public string NewSurname { get; set; }
public int NewAge { get; set; }
public int i=0 ;
public ObservableCollection<DataStorageModel> Models { get; set; }
//Event Handlers
public ICommand CreateClickCommand { get; set; }
public ICommand UpdateClickCommand { get; set; }
public ICommand DeleteClickCommand { get; set; }
public ViewModel()
{
CreateClickCommand = new RelayCommand(arg => CreateClickMethod());
UpdateClickCommand = new RelayCommand(arg => UpdateClickMethod());
DeleteClickCommand = new RelayCommand(arg => DeleteClickMethod());
Models = new ObservableCollection<DataStorageModel>() {};
}
private void CreateClickMethod()
{
Models.Add(new DataStorageModel() { Name = NewName, Surname = NewSurname, Age = NewAge, Count=i++ });
}
private void UpdateClickMethod()
{}
private void DeleteClickMethod()
{}
}
I want to change data and delete it. As i good understand, I need select count from ListBoxItems and delete(update) this count in ObservableCollection.
How can I work with XAML code from ViewModel class ?
How can I initiliaze Storage in ViewModel ?
Or in MVVM is the better way to resolve this problem ?
When you want to delete a model from the ListBox you typically need some way to identify the selected ListBoxItems (or models) that you want to delete; for that, consider having an IsSelected property on your models and bind it to a CheckBox inside the ListBoxItem data template.
Now, when you click on delete, the delete command can then easily look into the Models list and see which items are selected for deletion. After it deletes the items, it can then enumerate over the collection and recalculate the count value for the remaining items and update the field in the view model.
So, you don't have to access the XAML to update the count of the models. If you make the count property mutable then you wouldn't have to reinitialize the storage after you delete items from the list.
I added code t the Model
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Also added checkbox with bindin to View.
<ListBox x:Name="Storage" Background="Gray" FontSize="14" ItemsSource="{Binding Path=Models, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="60" Width="400" >
<CheckBox x:Name="checkbox" IsChecked="{Binding Path=IsSelected, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock x:Name="nameblock" Text="{Binding Name}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But IsSelected var doesn't change when I check checkbox in item
Why ?

WPF MVVM moving a UserControl from one ObservableCollection to another by event

I have a checklist view that has 2 ScrollViewers. One checklist is for incomplete items, the other is for complete items. They are populated by 2 separate observable collections and bound to by ItemsControls.
The UserControl has a button, when clicked will move that 'check' to the other collection.
Currently the way I have this setup is in the ViewModel that's the DataContext for the UserControl there is a public event that is subscribed to by the main window's VM by using:
((CheckItemVM) ((CheckListItem) cli).DataContext).CompleteChanged += OnCompleteChanged;
where cli is the checklist item.
then the OnCompleteChanged finds the appropriate View object by using:
foreach (object aCheck in Checks)
{
if (aCheck.GetType() != typeof (CheckListItem)) continue;
if (((CheckListItem) aCheck).DataContext == (CheckItemVM) sender)
{
cliToMove = (CheckListItem) aCheck;
break;
}
}
It's pretty obvious this breaks MVVM and I'm looking for a way around it (CheckListItem is the View, and CheckItemVM is it's DataContext ViewModel). Reasoning for the boxed type is I've got another UserControl that will have instances inside both, which are basically section labels, and I need to be able to sort my observable collections where there is an association between the checklistitem to a specific section by name.
This can be done in MVVM using commands, and bindings....
The idea that I propouse here is to create a command in the Windows view model, that manage the check command, and this command to receive the item view model in the params, then manage the the things in the command. I'm going to show you a simple example, using MvvmLight library:
The model:
public class ItemViewModel : ViewModelBase
{
#region Name
public const string NamePropertyName = "Name";
private string _name = null;
public string Name
{
get
{
return _name;
}
set
{
if (_name == value)
{
return;
}
RaisePropertyChanging(NamePropertyName);
_name = value;
RaisePropertyChanged(NamePropertyName);
}
}
#endregion
#region IsChecked
public const string IsCheckedPropertyName = "IsChecked";
private bool _myIsChecked = false;
public bool IsChecked
{
get
{
return _myIsChecked;
}
set
{
if (_myIsChecked == value)
{
return;
}
RaisePropertyChanging(IsCheckedPropertyName);
_myIsChecked = value;
RaisePropertyChanged(IsCheckedPropertyName);
}
}
#endregion
}
A simple model with two property, one for the name (an identifier) and another for the check status.
Now in the Main View Model, (or Windows view model like you want)....
First the Collections, one for the checked items, and another for the unchecked items:
#region UncheckedItems
private ObservableCollection<ItemViewModel> _UncheckedItems;
public ObservableCollection<ItemViewModel> UncheckedItems
{
get { return _UncheckedItems ?? (_UncheckedItems = GetAllUncheckedItems()); }
}
private ObservableCollection<ItemViewModel> GetAllUncheckedItems()
{
var toRet = new ObservableCollection<ItemViewModel>();
foreach (var i in Enumerable.Range(1,10))
{
toRet.Add(new ItemViewModel {Name = string.Format("Name-{0}", i), IsChecked = false});
}
return toRet;
}
#endregion
#region CheckedItems
private ObservableCollection<ItemViewModel> _CheckedItems;
public ObservableCollection<ItemViewModel> CheckedItems
{
get { return _CheckedItems ?? (_CheckedItems = GetAllCheckedItems()); }
}
private ObservableCollection<ItemViewModel> GetAllCheckedItems()
{
var toRet = new ObservableCollection<ItemViewModel>();
foreach (var i in Enumerable.Range(11, 20))
{
toRet.Add(new ItemViewModel { Name = string.Format("Name-{0}", i), IsChecked = true });
}
return toRet;
}
#endregion
And the command:
#region CheckItem
private RelayCommand<ItemViewModel> _CheckItemCommand;
public RelayCommand<ItemViewModel> CheckItemCommand
{
get { return _CheckItemCommand ?? (_CheckItemCommand = new RelayCommand<ItemViewModel>(ExecuteCheckItemCommand, CanExecuteCheckItemCommand)); }
}
private void ExecuteCheckItemCommand(ItemViewModel item)
{
//ComandCode
item.IsChecked = true;
UncheckedItems.Remove(item);
CheckedItems.Add(item);
}
private bool CanExecuteCheckItemCommand(ItemViewModel item)
{
return true;
}
#endregion
The magic here could be in the Data binding, in this case I used command parameter and the FindAncestor binding, check the Data Template:
<DataTemplate x:Key="UncheckedItemDataTemplate">
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top"/>
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="{Binding IsChecked}" IsEnabled="False"/>
<Button Content="Check" Width="75" Command="{Binding DataContext.CheckItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" CommandParameter="{Binding Mode=OneWay}"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="CheckedItemDataTemplate">
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top"/>
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="{Binding IsChecked}" IsEnabled="False"/>
</StackPanel>
</Grid>
</DataTemplate>
One data template for checked items, and another for unchecked items. Now the usage, this is simpler:
<ListBox Grid.Row="2" Margin="5" ItemsSource="{Binding UncheckedItems}" ItemTemplate="{DynamicResource UncheckedItemDataTemplate}"/>
<ListBox Grid.Row="2" Margin="5" Grid.Column="1" ItemsSource="{Binding CheckedItems}" ItemTemplate="{DynamicResource CheckedItemDataTemplate}"/>
This is a cleaner solution, hope is helps.

Databinding a nested List property in WPF

I am using the following XAML code to display a list of checked list boxes.
<ListBox x:Name="lbxProjects" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ListBox x:Name="lbxUnits" ItemsSource="{Binding Units}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox Content="{Binding unit.Name}" IsChecked="{Binding isSelected}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The data model is as follows
public class ProjectsListBox
{
public Project project { get; set; }
public List<UnitsCheckBox> Units = new List<UnitsCheckBox>();
public ProjectsListBox(Project project)
{
this.project = project;
foreach(var d in project.Documents)
{
Units.Add(new UnitsCheckBox(d));
}
}
}
public class UnitsCheckBox : INotifyPropertyChanged
{
public Document unit { get; set; }
private bool isselected = true;
public bool isSelected
{
get { return isselected; }
set
{
isselected = value;
NotifyPropertyChanged("isSelected");
}
}
public UnitsCheckBox(Document d)
{
unit = d;
}
}
I am assigning the data source for the parent listbox like
lbxProjects.DataContext = projectsList;
The code creates the child list boxes but not the checkboxes inside the child list boxes. What am i missing?
How should WPF resolve unit.Name?
If the type UnitsCheckBox contains a Name property, then the CheckBox's Content should be bound to Name:
Content="{Binding Name}"
You should always specify the type of your DataTemplate:
<DataTemplate DataType="{x:Type local:UnitsCheckBox}" ...>
Those are the probable problems but I can't be sure unless you give us the UnitsCheckBox code.

Categories