【发布时间】:2018-11-15 17:37:55
【问题描述】:
我有一个ListBox,其ItemSource 绑定到我的PointStylesViewModel 中包含的PointStyleModel 对象集合。 PointStyleModel 类具有三个属性:大小、名称和颜色(颜色的类型为 GeoColor - 第三方库对象)。
TextBox 绑定到 Name 属性。
xceed 工具包IntegerUpDown 绑定到Size。
一个 xceed 工具包ColorPicker 绑定到颜色。
目前,每当用户选择列表中的新项目时,三个控件都会正确更新。但是,如果用户在 UI 中更改 IntegerUpDown 或 ColorPicker 的值,然后在列表中选择不同的项目,则 UI 不会显示正确的值。我不希望仅仅因为用户更改 UI 中的值而更新属性。 TextBox 绑定到 Name 工作正常。我尝试了各种绑定模式和 updatesourcetriggers,但都没有成功。
这是我的模型类:
public class PointStyleModel
{
public int Size
{
get;
set;
}
public string Name
{
get;
set;
}
public GeoColor Color
{
get;
set;
}
}
这是我的视图模型:
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
}
}
以下是我观点的相关部分:
<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>
这是一个问题的例子:
在第一张图片中,我选择了 RedSquare6,它使用我的 VM 中的 PointStyleColor 属性填充 ColorPicker。它从 SelectedPointStyle 的 Color 属性中获取该值。这很好用。
在第二张图片中,我从 ColorPicker 控件中选择了一种新颜色,在本例中为粉红色。这不应该改变任何属性。我只是在更改控件的颜色。 RedSquare6 的 Color 属性仍应为 Red。
在第三张图片中,我选择了 GreenSquare6。 ColorPicker 控件现在应该显示为绿色,但它保持为粉红色,并且我的 VM 中的 PointStyleColor getter 不再被命中。
Size IntegerUpDown 控件也是如此。
选择新颜色时,颜色选择器和 intupdown 没有更新。我注意到更改选择时没有命中属性。 PointStyleName 是。
编辑:这是我的 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) => { };
}
}
这是正在发生的事情的 GIF。我在这里测试 intupdown 控件:
正如您在上面看到的,一旦我将 IntUpDown 的值更改为 8,它就会保持在该值,即使所选项目正在更改,这应该将值更改为 6。
编辑:这是一个显示问题的小示例应用程序: https://www.dropbox.com/s/l3gu3nj915cstoa/TestApp.zip?dl=0
【问题讨论】:
-
据我所见,没有任何东西在调用
PointStyleSize或PointStyleColor。当SelectedPointStyle改变时,没有逻辑告诉界面改变颜色或大小。 -
你是对的。你是否知道,在使用 Fody 的 propertychanged 时,如何通知其他属性的变化?
标签: c# wpf mvvm data-binding xceed