简体   繁体   English

具有IEnumerable的ComboBox <Brush> 作为ItemsSource和SelectedItem异常

[英]ComboBox with IEnumerable<Brush> as ItemsSource and SelectedItem exception

I have this issue with ComboBox that uses IEnumerable<Brush> as ItemsSource; 我在使用IEnumerable<Brush>作为ItemsSource的ComboBox中遇到此问题; the problem lies when I (programmatically) try to set SelectedItem. 问题出在我(以编程方式)尝试设置SelectedItem时。 Here is the code that describes the problem: 这是描述问题的代码:

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;
    }
}

And here is xaml code: 这是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>

After the get on the White property is called I get an Exception: Cannot set a property on object '#FFFFFFFF' because it is in a read-only state . 调用get on White属性后,我得到一个异常: 无法在对象'#FFFFFFFF'上设置属性,因为它处于只读状态 If i leave White (white_) as null, everything works just fine. 如果我将White(white_)保留为null,则一切正常。

Using Reflector I've traced down where the problem appears to be occuring. 使用Reflector,我已经找到了可能出现问题的地方。 Inside Selector.ItemSetIsSelected , it takes the new SelectedItem and does the following: Selector.ItemSetIsSelected内部,它采用新的SelectedItem并执行以下操作:

  • If the container of the element is a DependencyObject it sets the IsSelectedProperty on the container to true . 如果该元素的容器DependencyObject ,则将容器上的IsSelectedProperty设置为true
  • Otherwise if the element is a DependencyObject it sets the IsSelectedProperty on the element to true . 否则,如果元素DependencyObject ,则将元素上的IsSelectedProperty设置为true

That second part is where the failure comes into play, the Brush objects you've chosen are Read-Only. 第二部分是发生故障的地方,您选择的Brush对象是只读的。 Because the Selector.ItemSetIsSelected is somewhat broken in this case, you have two options. 因为在这种情况下Selector.ItemSetIsSelected有点破损,所以您有两个选择。

Option 1 , you just call .Clone() on the Brush object returned from the Converter. 选项1 ,您只需在Converter返回的Brush对象上调用.Clone()即可。

colors_ = (from p in typeof(Brushes).GetProperties()
    select ((Brush)converter.ConvertFromString(p.Name)).Clone()).ToList();

EDIT: You should go with Option 1...Option 2 is the longwinded way to fix the problem 编辑:您应该使用选项1 ...选项2是解决问题的漫长方法

Option 2 , you could wrap the Brush objects into one more object: 选项2 ,您可以将Brush对象包装成另一个对象:

public class BrushWrapper
{
    public Brush Brush { get; set; }
}

You then update the data template paths: 然后,您更新数据模板路径:

<Border Background="{Binding Path=Brush}" />

and

<TextBlock Text="{Binding Path=Brush}" />

Finally, you update the ViewModel : 最后,您更新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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM