I have a ListBox
whose ItemSource
is bound to a collection of PointStyleModel
objects which is contained in my PointStylesViewModel
. The PointStyleModel
class has three properties: Size, Name, and Color (Color is of type GeoColor - a third party library object).
A TextBox
is bound to the Name
property.
An xceed toolkit IntegerUpDown
is bound to Size.
An xceed toolkit ColorPicker
is bound to Color.
Currently, whenever the user selects a new item on the list, the three controls are updated properly. But if the user were to change a value of the IntegerUpDown or the ColorPicker in the UI, and then select a different item in the list, the UI doesn't display the correct value. I don't want the properties being updated just because the user changes a value in the UI. The TextBox
bound to Name
works fine. I've tried the various binding modes and updatesourcetriggers but no luck.
Here's my model class:
public class PointStyleModel
{
public int Size
{
get;
set;
}
public string Name
{
get;
set;
}
public GeoColor Color
{
get;
set;
}
}
Here's my viewmodel:
public class PointStylesViewModel : ViewModelBase //using Fody's PropertyChangedInterface in the base class
{
public ObservableCollection<PointStyleModel> PointStyles { get; set; } //the listbox is bound to this
public PointStyleModel SelectedPointStyle { get; set; } //bound to the listboxe's selected item
public string PointStyleName { get { return SelectedPointStyle.Name; } }
public Color PointStyleColor
{
get
{
return Color.FromArgb(SelectedPointStyle.Color.AlphaComponent, SelectedPointStyle.Color.RedComponent, SelectedPointStyle.Color.GreenComponent, SelectedPointStyle.Color.BlueComponent); //Need to convert GeoColor to Color
}
}
public int PointStyleSize { get { return SelectedPointStyle.Size; } }
public PointStylesViewModel()
{
PointStyles = new ObservableCollection<PointStyleModel>();
AddDefaultPointStyles(); //add some default styles
SelectedPointStyle = PointStyles.First(); //select the first item in the list when starting up
}
}
Here's relevant sections of my view:
<TabItem DataContext="{Binding Path=PointStylesViewModel, Source={StaticResource ViewModelLocator}}">
<Grid>
<ListBox ItemsSource="{Binding PointStyles}" SelectedItem="{Binding SelectedPointStyle}" DisplayMemberPath="Name"/>
<TextBox Text="{Binding PointStyleName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
<GroupBox Header="Paint">
<Grid>
<xctk:ColorPicker SelectedColor="{Binding Path=PointStyleColor, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" DisplayColorAndName="False" DisplayColorTooltip="True"/>
<xctk:IntegerUpDown Value="{Binding PointStyleSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Maximum="20" Minimum="0" />
</Grid>
</GroupBox>
</Grid>
</TabItem>
Here's an example of the problem:
First I select an item in the listbox. Everything is populated correctly.
Now I'll change the color size on the UI only:
And then I'll select another item from the list:
In the first pic, I select RedSquare6 and it populates the ColorPicker with the PointStyleColor property in my VM. It's getting that value from the SelectedPointStyle's Color property. This works fine.
In the 2nd image, I select a new color from the ColorPicker control, pink in this case. This should NOT CHANGE any property. I'm just changing the Control's color. RedSquare6's Color property should still be Red.
In the 3rd image, I select GreenSquare6. The ColorPicker control should display Green now, but it stays on Pink, and the PointStyleColor getter in my VM is no longer being hit.
Same for the Size
IntegerUpDown control.
The color picker and intupdown did not update when selecting a new color. I noticed the properties were not being hit when changing the selection. The PointStyleName
was though.
Edit: Here's my ViewModelBase:
using PropertyChanged;
using System.ComponentModel;
namespace WpfApp1.ViewModels
{
/// <summary>
/// A base model that fires Property Changed events as needed
/// </summary>
[AddINotifyPropertyChangedInterface]
public class ViewModelBase : INotifyPropertyChanged
{
/// <summary>
/// The event is fired when any child property changes its value
/// </summary>
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
}
}
Here's a gif of what is happening. I'm testing the intupdown control here:
As you can see above, as soon as I change the value of the IntUpDown to 8, it stays at that value even though the selected item is changing which should change the value to 6.
Edit: Here's a small sample app showing the issue: https://www.dropbox.com/s/l3gu3nj915cstoa/TestApp.zip?dl=0