[英]ComboBox with IEnumerable<Brush> as ItemsSource and SelectedItem exception
我在使用IEnumerable<Brush>
作为ItemsSource的ComboBox中遇到此问题; 问题出在我(以编程方式)尝试设置SelectedItem时。 这是描述问题的代码:
private readonly List<Brush> colors_;
private Brush white_;
ViewModelConstructor()
{
colors_ = (from p in brushes_type.GetProperties()
select (Brush)converter.ConvertFromString(p.Name)).ToList();
white_ = colors_.Single(b => b.ToString() == "#FFFFFFFF");
}
public IEnumerable<Brush> Colors
{
get { return colors_; }
}
public Brush White
{
get { return white_; }
set
{
if (white_ != value)
white_ = value;
}
}
这是xaml代码:
<ComboBox ItemsSource="{Binding Path=Colors}"
SelectedItem="{Binding Path=White}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1"
BorderBrush="Black"
Width="20"
Height="12"
SnapsToDevicePixels="True"
Margin="0,0,4,0">
<Border Background="{Binding}"/>
</Border>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
调用get on White属性后,我得到一个异常: 无法在对象'#FFFFFFFF'上设置属性,因为它处于只读状态 。 如果我将White(white_)保留为null,则一切正常。
使用Reflector,我已经找到了可能出现问题的地方。 在Selector.ItemSetIsSelected
内部,它采用新的SelectedItem
并执行以下操作:
DependencyObject
,则将容器上的IsSelectedProperty
设置为true
。 DependencyObject
,则将元素上的IsSelectedProperty
设置为true
。 第二部分是发生故障的地方,您选择的Brush
对象是只读的。 因为在这种情况下Selector.ItemSetIsSelected
有点破损,所以您有两个选择。
选项1 ,您只需在Converter返回的Brush对象上调用.Clone()即可。
colors_ = (from p in typeof(Brushes).GetProperties()
select ((Brush)converter.ConvertFromString(p.Name)).Clone()).ToList();
编辑:您应该使用选项1 ...选项2是解决问题的漫长方法
选项2 ,您可以将Brush对象包装成另一个对象:
public class BrushWrapper
{
public Brush Brush { get; set; }
}
然后,您更新数据模板路径:
<Border Background="{Binding Path=Brush}" />
和
<TextBlock Text="{Binding Path=Brush}" />
最后,您更新ViewModel
:
private readonly List<BrushWrapper> colors_;
private BrushWrapper white_;
public ColorViewModel()
{
colors_ = (from p in typeof(Brushes).GetProperties()
select new BrushWrapper {
Brush = (Brush)converter.ConvertFromString(p.Name)
}).ToList();
white_ = colors_.Single(b => b.Brush.ToString() == "#FFFFFFFF");
}
public List<BrushWrapper> Colors
{
get { return colors_; }
}
public BrushWrapper White
{
get { return white_; }
set
{
if (white_ != value)
white_ = value;
}
}
这里只是一个黑暗的镜头(当前无法尝试),但是绑定SelectedValue而不是SelectedItem怎么样?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.