WPF Binding to Property of Element of ObservableCollection - c#

I'm working with a DataGrid in WPF and I'm trying to perform some data binding that it a little more complex than I'm used to. I have an ObservableCollection of a class that also implements an ObservableCollection of a subclass. I'm trying to bind the IsChecked property of a CheckBox to a value on that subclass and no matter when I try I can't seem to get it to work. Hopefully I'm just missing something simple.
In my main program I have the following, and it works fine for detecting changes to "SomeProperty" on the "MyDevice" class:
ObservableCollection<MyDevice> MyDevices = new ObservableCollection<MyDevice>();
DevicesGrid.ItemSource = MyDevices;
My class definition is below:
public class MyDevice : INotifyPropertyChanged
{
public class Input : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged([CallerMemberName] string PropertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
private bool _SyncDetected;
public bool SyncDetected
{
get { return _SyncDetected; }
set { _SyncDetected = value; RaisePropertyChanged(); }
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged([CallerMemberName] string PropertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
private bool _SomeProperty;
public bool SomeProperty
{
get { return _SomeProperty; }
set { _SomeProperty = value; RaisePropertyChanged(); }
}
public ObservableCollection<Input> MyInputs = new ObservableCollection<Input>() { new Input(), new Input() };
}
And this is my XAML:
<DataGrid x:Name="DevicesGrid" Margin="10,80,10,10" AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="ContextMenu" Value="{StaticResource DeviceRowContextMenu}"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Sync/Hotplug" IsReadOnly="True" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2,2,2,2" VerticalAlignment="Center" HorizontalAlignment="Center">
<CheckBox Margin="2,2,2,2" IsHitTestVisible="False" IsChecked="{Binding MyInputs[0].SyncDetected}" Content="In1"/>
<CheckBox Margin="2,2,2,2" IsHitTestVisible="False" IsChecked="{Binding MyInputs[1].SyncDetected}" Content="In2"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I'm really new at working with WPF so any help is appreciated. Thanks.

Here is something wrong:
public ObservableCollection<Input> MyInputs = new ObservableCollection<Input>() { new Input(), new Input() };
MyDevice.MyInputs is a field, not a property, so the binding system cannot find it through reflection.

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

WPF checkbox IsChecked two way binding not working

the following code I wrote for two way binding. The UI gets updated when anything from code changes but vice versa doesn't work, the UI doesn't change the data code when the checkbox is clicked by the user. Appreciate if anybody sheds some light on the solution.
XAML Code
<DataGrid ItemsSource="{Binding StatusItems}" Name="DataGridUploadingRevitFiles" Margin="5"
IsReadOnly="False" SelectionMode="Single" CanUserAddRows="True"
AutoGenerateColumns="False" SelectionUnit="Cell" Height="Auto">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Update" Width=".5*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Width="200"
IsChecked="{Binding Path=IsUpdateAbleFile,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Model [FamilyStatusItem.cs]
public class FamilyStatusItem : INotifyPropertyChanged
{
private bool _isUpdateAbleFile;
public bool IsUpdateAbleFile
{
get => this._isUpdateAbleFile;
private set
{
this._isUpdateAbleFile = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ViewModel [FamilyStatusViewItem.cs]
public class FamilyStatusViewItem
{
public ObservableCollection<FamilyStatusItem> StatusItems { get; set; }
public FamilyStatusViewItem()
{
this.StatusItems = new ObservableCollection<FamilyStatusItem>();
}
}
Your setter is private which means it can’t be called from the outside. Thus when you tick or untick the checkbox it can’t be called and the property retains the old state.
Solution: Remove the private modifier.
Try to use public setter
public bool IsUpdateAbleFile
{
get => this._isUpdateAbleFile;
set
{
this._isUpdateAbleFile = value;
OnPropertyChanged();
}
}
You are having a private setter
private set
{
this._isUpdateAbleFile = value;
OnPropertyChanged();
}
Change this to a public, then it should work.

Databinding to an Object property fails, to the parent it is working

I tried to bind a property to a nested object, but it fails.
I have taken a look at those questions, but i think i made another mistake somewhere else. Maybe someone can give i hind.
WPF: How to bind to a nested property?
binding to a property of an object
To upper slider/textbox has a correct binding while the lower one fails to do so.
I have two sliders with corrosponding textboxes:
<StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBox Text="{Binding Path= boundnumber, Mode=TwoWay, FallbackValue='binding failed'}" ></TextBox>
<Slider Value="{Binding Path= boundnumber, Mode=TwoWay}" Width="500" Maximum="1000" ></Slider>
</StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{Binding Path=myDatarow}">
<TextBox Text="{Binding Path= boundnumber, Mode=TwoWay, FallbackValue='binding failed'}" ></TextBox>
<Slider Value="{Binding Path= boundnumber, Mode=TwoWay}" Width="500" Maximum="1000" ></Slider>
</StackPanel>
</StackPanel>
Code behind:
public partial class MainWindow : INotifyPropertyChanged
{
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
private int _boundnumber;
public int boundnumber
{
get { return _boundnumber; }
set
{
if (value != _boundnumber)
{
_boundnumber = value;
OnPropertyChanged();
}
}
}
Datarow myDatarow = new Datarow(11);
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
class Datarow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
public Datarow()
{
}
public Datarow(int number)
{
boundnumber = number;
}
private int _boundnumber;
public int boundnumber
{
get { return _boundnumber; }
set
{
if (value != _boundnumber)
{
_boundnumber = value;
OnPropertyChanged();
}
}
}
}
You need to expose your myDatarow into a public property like your boundnumber.
private DataRow _myDatarow = new DataRow(11);
public DataRow myDataRow
{
get { return _myDatarow; }
}
And just an additional advice.
It's better to separate your DataContext class from the MainWindow.

Complex databinding issue

Im trying develope a databound polyline canvas.
Currently I databind a list of classes each containing an pointcollection and an offset. However I want to customize each of these lines further eg, their colour. Therefore I want to create a List inside the class containing a polyline model class. Which contain a pointcollection, offset X, Y and data for the polylines colour.
Currently it looks like this:
<Canvas Name="PolyLineCanvas" Width ="100" Height="100">
<ItemsControl ItemsSource="{Binding WaypointList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=TracedPathLeft, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=TracedPathTop, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Polyline Stroke="Magenta" Points="{Binding TracedPath}" StrokeThickness="0.0244"></Polyline>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
And class:
public class WaypointListModel : INotifyPropertyChanged
{
public class Waypoint : INotifyPropertyChanged
{
ObservableCollection<Waypoint> wptList;
PointCollection tracedPath;
double tracedPathTop;
double tracedPathLeft;
public Waypoint(ObservableCollection<Waypoint> WptList)
{
wptList = WptList;
}
public PointCollection TracedPath
{
get
{
return tracedPath;
}
set
{
tracedPath = value;
}
}
public double TracedPathTop
{
get
{
return tracedPathTop;
}
set
{
tracedPathTop = value;
}
}
public double TracedPathLeft
{
get
{
return tracedPathLeft;
}
set
{
tracedPathLeft = value;
}
}
public void NotifyCanvas() //Method being called when pressing an update button
{
NotifyPropertyChanged("TracedPathTop");
NotifyPropertyChanged("TracedPathLeft");
NotifyPropertyChanged("TracedPath");
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
ObservableCollection<Waypoint> waypointList = new ObservableCollection<Waypoint>();
public ObservableCollection<Waypoint> WaypointList
{
get
{
return waypointList;
}
set
{
waypointList = value;
NotifyPropertyChanged("WaypointList");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Here is the polylineModel class I made (similar to the one present upwards):
class WayPointPolyline : INotifyPropertyChanged
{
SolidColorBrush tracedPathColour;
PointCollection tracedPath;
double tracedPathTop;
double tracedPathLeft;
public SolidColorBrush TracedPathColour
{
get
{
return tracedPathColour;
}
set
{
tracedPathColour = value;
NotifyPropertyChanged("TracedPathColour");
}
}
public PointCollection TracedPath
{
get
{
return tracedPath;
}
set
{
tracedPath = value;
NotifyPropertyChanged("TracedPath");
}
}
public double TracedPathTop
{
get
{
return tracedPathTop;
}
set
{
tracedPathTop = value;
NotifyPropertyChanged("TracedPathTop");
}
}
public double TracedPathLeft
{
get
{
return tracedPathLeft;
}
set
{
tracedPathLeft = value;
NotifyPropertyChanged("TracedPathLeft");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
However in the class called Waypoint
I want to replace PointCollection with:
public List<WayPointPolyline > TracedPaths
{
get
{
return tracedPaths;
}
set
{
tracedPaths = value;
}
}
The xaml is where the hard part comes, since currently it adds only a single pointcollection per class addded in the List, what I need is a List where you add x classes, class x can contain data for y lines. Any idea what to do?
Thanks on advance!
Credits to Chris Eelmaa for the hint!
Xaml should look like this: I have not noticed any drastic difference in performance. However as an amatuer it would be interesting knowing if the code below is "too messy"
<Canvas Name="PolyLineCanvas" Width ="100" Height="100">
<ItemsControl ItemsSource="{Binding WaypointList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding TracedPathList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=TracedPathLeft, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=TracedPathTop, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Polyline StrokeDashArray="{Binding TracedPathDashStyle}" Stroke="{Binding TracedPathColour}" Points="{Binding TracedPath}" StrokeThickness="0.0244"></Polyline>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>

MVVM: Binding to List IsSelected while tracking IsSynchronizedWithCurrentItem

I'm tracking ListView selection changes in an MVVM design by binding to IsSelected. I also need to track the current item by enabling IsSynchronizedWithCurrentItem.
I find that when I have two ListView binding to the same collection I get the InvalidOperationException: "Collection was modified; enumeration operation may not execute." It seems to be a synchonization error between the two ListViews; one is triggering a PropertyChanged event while the other is updating the Selector perhaps?
I can't figure out how to get around this other than forgoing use of IsSynchronizedWithCurrentItem and managing it myself. Any ideas?
Thanks.
The ViewModel and code behind:
public class Item : INotifyPropertyChanged
{
public string Name{ get; set; }
public bool IsSelected
{
get { return isSelected; }
set { isSelected = value; OnPropertyChanged("IsSelected"); }
}
private bool isSelected;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class ViewModel
{
public ViewModel()
{
Items = new ObservableCollection<Item>()
{
new Item(){Name = "Foo"},
new Item(){Name = "Bar"}
};
}
public ObservableCollection<Item> Items { get; private set; }
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
The XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="100" Width="100">
<StackPanel>
<ListView DataContext="{Binding Items}" ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True" SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name, Mode=OneWay}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView DataContext="{Binding Items}" ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True" SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name, Mode=OneWay}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>
I cannot offer a direct fix for your problem. However, I do have a solution that will work.
What you can do is introduce a second property on your View Model called 'SelectedItem' that will hold a reference to the Item that is selected in your ListView. In addition, in your View Model you listen for the PropertyChanged event. If the associated Property Name is IsSelected then you update the SelectedItem property to be the sender of that event (the Item that now has IsSelected = true). You can then bind the SelectedItem property of the ListView to the property of the same name of the ViewModel class.
My code for the revised ViewModel class is below.
public class ViewModel : INotifyPropertyChanged
{
private Item _selectedItem;
public ViewModel()
{
Items = new ObservableCollection<Item>()
{
new Item {Name = "Foo"},
new Item {Name = "Bar"}
};
foreach ( Item anItem in Items )
{
anItem.PropertyChanged += OnItemIsSelectedChanged;
}
}
public ObservableCollection<Item> Items { get; private set; }
public Item SelectedItem
{
get { return _selectedItem; }
set
{
// only update if the value is difference, don't
// want to send false positives
if ( _selectedItem == value )
{
return;
}
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnItemIsSelectedChanged(object sender, PropertyChangedEventArgs e)
{
if ( e.PropertyName != "IsSelected" )
{
return;
}
SelectedItem = sender as Item;
}
private void OnPropertyChanged(string propertyName)
{
if ( PropertyChanged != null )
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The issue seems to happen when you bind to a listbox's IsSelected and use SelectionMode='Single'
I found that changing the SelectionMode = 'Multiple' and then just added logic to the ViewModel to ensure that there was ever only one item with IsSelected set to true worked.

Categories