Multi-Select ListBox Binding Issue - c#

I have created a custom control derived from a ListBox and I am having issues getting the "SelectedItemsList" to bind to it's corresponding property in the view model.
The problem: The selected items in the list box do not make it into the property it is bound to in the view model. The list box allows multiple selections but none of these make into the List in the view model.
MultiSelectListBox:
public class MultiSelectListBox : ListBox
{
public MultiSelectListBox() { }
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register(
"SelectedItemsList",
typeof(IList),
typeof(MultiSelectListBox),
new PropertyMetadata(default(IList)));
public IList SelectedItemsList
{
get { return (IList) GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
}
declaration in MainWindow.xaml:
<local:MultiSelectListBox
DataContext="{StaticResource viewModel}"
DockPanel.Dock="Left"
Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}"
ItemsSource="{Binding SelectedOutputtapeList}"
SelectionMode="Multiple"
SelectedItemsList="{Binding SelectedOutputTapes, Mode=TwoWay}"
HorizontalAlignment="Right"
Background="DeepSkyBlue"
Foreground="MidnightBlue"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Height="100"
Width="70"
Margin="5"/>
View Model (simplified):
public class BTLogFrontEndViewModel : ViewModelBase
{
private List<string> selectedOutputTapes;
public BTLogFrontEndViewModel()
{
selectedOutputTapes = new List<string>();
}
public List<string> SelectedOutputTapes
{
get
{
return selectedOutputTapes;
}
set
{
selectedOutputTapes = value;
OnPropertyChanged("SelectedOutputTapes");
}
}
}

One way is to not use a custom ListBox and use objects in your list that extend INotifyPropertyChanged:
<ListBox
Width="70"
Height="100"
HorizontalAlignment="Right"
Margin="5"
Background="DeepSkyBlue"
DockPanel.Dock="Left"
Foreground="MidnightBlue"
ItemsSource="{Binding SelectedOutputtapeList}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
SelectionMode="Multiple"
DisplayMemberPath="Description"
Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Assuming BTLogFrontEndViewModel is your DataContext:
public class BTLogFrontEndViewModel : ViewModelBase
{
private ObservableCollection<OutputTapeViewModel> m_SelectedOutputtapeList;
public ObservableCollection<OutputTapeViewModel> SelectedOutputtapeList
{
get
{
return m_SelectedOutputtapeList;
}
set
{
m_SelectedOutputtapeList = value;
NotifyPropertyChanged("SelectedOutputtapeList");
}
}
}
Where OutputTapeViewModel is declared like:
public class OutputTapeViewModel : ViewModelBase
{
private string m_Description;
public string Description
{
get
{
return m_Description;
}
set
{
m_Description = value;
NotifyPropertyChanged("Description");
}
}
private bool m_IsSelected;
public string IsSelected
{
get
{
return m_IsSelected;
}
set
{
m_IsSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
}
Important things to note is on the listbox I have added the DisplayMemberPath property for use of the description field in the OutputTapeViewModel class for what to show on the listbox. Also it has an item container style, which binds to the OutputTapeViewModel.IsSelected property when selected in the ListBox. This OutputTapeViewModel.IsSelected allows you to use the BTLogFrontEndViewModel.SelectedOutputtapeList property in such ways as:
var selectedItems = SelectedOutputtapeList.Where(item => item.IsSelected);
This only works in your case if you don't care about the overhead of doing the LINQ expression.

Related

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">

C# wpf listbox not updating from ObservableCollection

I'm trying to get the databinding I need to work with a ListBox.
I've parsed some data from a text file to a ObservableCollection<ViewModel> but the data isn't updating in the ListBox.
Here's some information:
The data which is written to from the parser:
class MainData
{
private static ObservableCollection<GroupViewModel> groupModelList = new ObservableCollection<GroupViewModel>();
public static ObservableCollection<GroupViewModel> GroupModelList
{
get { return groupModelList; }
}
}
What GroupViewModel holds (not everything but it's all the same):
class GroupViewModel : INotifyPropertyChanged
{
private GroupModel groupModel;
public event PropertyChangedEventHandler PropertyChanged;
public GroupViewModel()
{
groupModel = new GroupModel();
}
public string Name
{
get { return groupModel.name; }
set
{
if (groupModel.name != value)
{
groupModel.name = value;
InvokePropertyChanged("Name");
}
}
}
...
}
And what GroupModel Holds:
class GroupModel
{
public string name { get; set; }
}
This is how the parser adds new items to the GroupModelView:
if (split[0] == "group")
{
currentGroup = new GroupViewModel();
currentGroup.Name = split[1];
MainData.GroupModelList.Add(currentGroup);
}
I created a ListBox in my WPF application with these XAML options:
<Window x:Class="SoundManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SoundManager.ViewModels"
xmlns:vm2="clr-namespace:SoundManager.Code"
Title="MainWindow" Height="720" Width="1280">
<Window.Resources>
<vm:MainViewModel x:Key="MainViewModel" />
<vm2:MainData x:Key="MainData" />
</Window.Resources>
<ListBox Grid.Row="2" Height="484" HorizontalAlignment="Left" Margin="12,0,0,0" Name="lbFoundItems" VerticalAlignment="Top" Width="201" ItemsSource="{Binding Source={StaticResource MainData}, Path=GroupModelList/Name}" />
but for some reason the data isn't updating in the UI (new items aren't added visibly in the UI).
I've been just getting started with the MVVM pattern and databinding and I can't figure out what I'm doing wrong.
Thanks in advance!
GroupModelList/Name is not a valid property path here. Setting it like that does not make the ListBox show the Name property of the data items in the GroupModelList collection.
You would instead have to set the ListBox's DisplayMemberPath property:
<ListBox ItemsSource="{Binding Source={StaticResource MainData}, Path=GroupModelList}"
DisplayMemberPath="Name"/>
or set the ItemTemplate property:
<ListBox ItemsSource="{Binding Source={StaticResource MainData}, Path=GroupModelList}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Moreover, the GroupModelList property should not be static:
class MainData
{
private ObservableCollection<GroupViewModel> groupModelList =
new ObservableCollection<GroupViewModel>();
public ObservableCollection<GroupViewModel> GroupModelList
{
get { return groupModelList; }
}
}
Then you might have MainData as a property in your view model, and bind the ListBox like this:
<ListBox ItemsSource="{Binding Source={StaticResource MainViewModel},
Path=MainData.GroupModelList}" .../>

How to get a property of a type when Binding

I have a type called "MyType" and my Pivot's ItemsSource is bound to an ObservableCollection property called "DataSource" inside the "myFirstVM" ViewModel. Inside "MyType" i have the property Title. As you can see from my XAML the TextBlock is bound to MyProperty. How to make it return the current item Title?
So for example, If i am on the second PivotItem, I need the Title of the second item in the DataSource collection
XAML:
<Grid x:Name="LayoutRoot">
<Pivot Name="myPivot"
SelectedItem="{Binding myFirstVM.SelItem, Mode=TwoWay}"
ItemsSource="{Binding myFirstVM.DataSource}"
ItemTemplate="{Binding myFirstVM.OtherTemplate}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.myFirstVM.MyProperty, ElementName=myPivot}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
</Pivot>
</Grid>
myFirstVM code:
private ObservableCollection<MyType> _dataSource;
public ObservableCollection<MyType> DataSource
{
get
{
if (this._dataSource == null)
{
this._dataSource = new ObservableCollection<MyType>();
}
return this._dataSource;
}
set { }
}
public string MyProperty
{
get
{
if (null != this.SelItem)
{
return this.SelItem.Title;
}
return "no title";
}
set { }
}
private MyType _selItem;
public MyType SelItem
{
get
{
return _selItem;
}
set
{
_selItem = value;
RaisePropertyChanged("SelItem");
RaisePropertyChanged("MyProperty");
}
}
public ObservableCollection<MyOtherType> OtherDataSource
{
get
{
if (null != this.SelItem)
{
return this.SelItem.OtherCollection;
}
else
{
return new ObservableCollection<MyOtherType>();
}
}
set { }
}
private MyOtherType _selOtherItem;
public MyOtherType SelOtherItem
{
get
{
return _selSegment;
}
set
{
_selSegment = value;
RaisePropertyChanged("SelOtherItem");
RaisePropertyChanged("PartsDataSource");
}
}
public ObservableCollection<MyThirdType> ThirdDataSource
{
get
{
if (null != this.SelOtherItem)
{
return this.SelOtherItem.ThirdCollection;
}
else
{
return new ObservableCollection<MyThirdType>();
}
}
set { }
}
And these are my DataTemplates for the inner collections "OtherDataSource" and "ThirdDataSource", that are ListBoxes:
<DataTemplate x:Key="OtherTemplate">
<ListBox DataContext="{Binding Source={StaticResource Locator}}"
ItemsSource="{Binding myFirstVM.OtherDataSource}"
ItemTemplate="{StaticResource ThirdTemplate}"
SelectedItem="{Binding myFirstVM.SelOtherItem, Mode=TwoWay}">
</ListBox>
</DataTemplate>
<DataTemplate x:Key="ThirdTemplate">
<ListBox DataContext="{Binding Source={StaticResource Locator}}"
ItemsSource="{Binding myFirstVM.ThirdDataSource}"
ItemTemplate="{StaticResource FourthTemplate}">
</ListBox>
</DataTemplate>
EDIT: I updated the question with the full ViewModel, and the DataTemplates, as sugested by #olitee. The problem with this approach as you can see is that in the second, and third dataTemplate I have ListBoxes. I am using one ViewModel for all the things. Any ideas?
You need to do a little extra work. Your ViewModel is not currently aware of which item is selected. You could create a new property called 'SelectedItem', and bind the Pivots' SelectedItem value.
Then you can access the Selected Item in code.
<Grid x:Name="LayoutRoot">
<Pivot Name="myPivot"
Tag="{Binding}"
SelectedItem="{Binding myFirstVM.SelectedItem}"
ItemsSource="{Binding myFirstVM.DataSource}"
ItemTemplate="{Binding myFirstVM.ViewDataTemplate}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.myFirstVM.MyProperty, ElementName=myPivot}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
</Pivot>
</Grid>
Then your VM would look something like:
private ObservableCollection<MyType> _dataSource;
public ObservableCollection<MyType> DataSource
{
get
{
if (this._dataSource == null)
{
this._dataSource = new ObservableCollection<MyType>();
}
return this._dataSource;
}
set { }
}
public string MyProperty
{
get
{
if (this.SelectedItem != null)
{
return this.SelectedItem.Title;
}
else
{
return null;
}
}
}
private MyType _selectedItem;
public MyType SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnNotifyPropertyChanged("SelectedItem");
OnNotifyPropertyChanged("MyProperty");
}
}
Alternatively, if you're just wanting to fix up the text for presentation, and don't really require the SelectedItem in your VM, you could go with #Jehof's approach - but implement an IValueConvertor that performs the fix.
This should do the trick
<TextBlock Text="{Binding SelectedItem.Title, ElementName=myPivot}"/>
Bind the Text-Property to the SelectedItem property of the Pivot element. When the selected item of the Pivot changes the TextBlock should display the Title of the item.
This is the right XAML implementation:
SelectedItem="{Binding myFirstVM.SelectedItem, Mode=TwoWay}"
and in the code behind instead of OnNotifyPropertyChanged the ViewModel needs to inherit ViewModelBase, part of MVVM Light then in the setter of SelectedItem property:
RaisePropertyChanged("SelectedItem");

Binding a property to change the listbox items foreground individually for each item

I'm trying to change the foreground color of the items in the ListBox individually for each item, I've already posted a similar question but this one is more concrete.
I hoped that the state of the color is reserved for each item added to the ListBox, so I tried to create a property (in this case "HotkeysForeground"), bind it and change the color when the items are added in the "HotkeyManager_NewHotkey" event, the problem it's changing the foreground color for all the items in the ListBox.
How can I do that per item ?
Here is the ViewModel I use.
namespace Monkey.Core.ViewModel
{
using System;
using System.Collections.ObjectModel;
using System.Windows.Media;
using Monkey.Core.SystemMonitor.Accessibility;
using Monkey.Core.SystemMonitor.Input;
public class MainWindowViewModel : WorkspaceViewModel
{
private readonly FocusManager _focusManager;
private readonly HotkeyManager _hotkeyManager;
private readonly ObservableCollection<string> _hotkeys;
private Color _foregroundColor;
private string _title;
public MainWindowViewModel()
{
_hotkeys = new ObservableCollection<string>();
_hotkeyManager = new HotkeyManager();
_hotkeyManager.NewHotkey += HotkeyManager_NewHotkey;
_focusManager = new FocusManager();
_focusManager.Focus += FocusManager_Focus;
}
public Color HotkeysForeground
{
get
{
return _foregroundColor;
}
set
{
_foregroundColor = value;
OnPropertyChanged(() => HotkeysForeground);
}
}
public ReadOnlyObservableCollection<string> Hotkeys
{
get
{
return new ReadOnlyObservableCollection<string>(_hotkeys);
}
}
public string Title
{
get
{
return _title;
}
set
{
_title = value;
OnPropertyChanged(() => Title);
}
}
protected override void OnDispose()
{
base.OnDispose();
_hotkeyManager.Dispose();
_focusManager.Dispose();
}
private void FocusManager_Focus(object sender, FocusManagerEventArgs e)
{
Title = e.Title;
}
private void HotkeyManager_NewHotkey(object sender, EventArgs eventArgs)
{
HotkeysForeground = _hotkeys.Count <= 2 ? Colors.Blue : Colors.Brown;
_hotkeys.Clear();
foreach (var hotkey in _hotkeyManager.GetHotkeys())
{
_hotkeys.Add(hotkey);
}
}
}
}
Here is the view.
<Window x:Class="Monkey.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="{Binding Mode=OneWay, Path=Title, UpdateSourceTrigger=PropertyChanged}" Height="200" Width="200" ShowInTaskbar="False" WindowStyle="ToolWindow" Topmost="True" ResizeMode="CanResizeWithGrip" AllowsTransparency="False">
<Window.Resources>
<SolidColorBrush Color="{Binding HotkeysForeground}" x:Key="HotkeysBrush"/>
</Window.Resources>
<ListBox
Canvas.Left="110"
Canvas.Top="74"
Name="HotkeyList"
Height="Auto" Width="Auto" HorizontalContentAlignment="Left"
BorderThickness="0"
ScrollViewer.CanContentScroll="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=Hotkeys}" VerticalAlignment="Stretch" VerticalContentAlignment="Center" FontSize="20">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}" Foreground="{StaticResource HotkeysBrush}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
Thank you in advance.
Sounds like bad design to me. If you have more data than a hotkey string just create a class and store the color together with the display string as separate properties.
Edit: Example:
public class HotkeyViewModel
{
private readonly string _DisplayString;
public string DisplayString { get { return _DisplayString; } }
private readonly Color _Color;
public Color Color { get { return _Color; } }
public HotkeyViewModel(string displayString, Color color)
{
_DisplayString = displayString;
_Color = color;
}
}
You can also make the properties editable, but if any bindings should update you need to implement INPC.
The new collection should then be of type ObservableCollection<HotkeyViewModel> and the template has two bindings:
<DataTemplate>
<Label Content="{Binding DisplayString}">
<Label.Background>
<SolidColorBrush Color="{Binding Color}" />
</Label.Background>
</Label>
</DataTemplate>
(You could also make the property a Brush and bind directly to Background)

Checkbox WPF MVVM

Hi all i have problem in this code, please help me..
I have view
<StackPanel Orientation="Horizontal" Margin="3">
<Label Content="Audit Type" MinWidth="100"/>
<Label Content=":"/>
<StackPanel Orientation="Vertical">
<ListBox ItemsSource="{Binding Items}" Margin="3" SelectionMode="Extended" MinWidth="180">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Name="check" Content="{Binding Value}" IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="3" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
and for View model
private List<AuditTypeExport> _items;
private List<string> _value;
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public List<AuditTypeExport> Items
{
get { return _items; }
}
public List<string> Value
{
get { return _value; }
set
{
_value = value;
OnPropertyChanged("Value");
}
}
And ViewModel Constractor
_items = _model.GetAuditType();
_value = _model.GetAuditType().Select(item => item.Name).ToList();
For your information
public class AuditTypeExport
{
private int _id;
private string _name;
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
The result : checkbox appeares, but the content doesn't and I don't have a clue why.
Question Number 2 : I want to get the value back, how can I do that?
Thank you
It is unclear how you are using your ViewModel. Is that bound to the form? Or each item in the ListBox?
It looks like your ListBox is bound to the Items collection of your VM, so the ItemTemplate will be used with a AuditTypeExport as the data context. You are binding to "Value" and "IsChecked" properties which do not exist on the AuditTypeExport class.
What you are trying to do here is bind a property of type List<String> Value to CheckBox's Content property which is of type Object.
To simplify, you are assigning a collection of strings to a string. Which is not a good thing. And that is why it does not work.
Try using ItemsControl to show Value property or use an IValueConverter to convert List<String> to comma separated string.

Categories