Saturday, September 15, 2012

Unable to bind a ResourceDictionary item to Rectangle.Child

Unable to bind a ResourceDictionary item to Rectangle.Child

When I try to bind a ResourceDictionary item against Rectangle.Child, I get an exception:

ArgumentException: Value does not fall within the expected range.

Here is an example:

<UserControl.Resources>     <local:PersonConverter x:Key="MyConverter"/> </UserControl.Resources>  <ListBox ItemsSource="{Binding Persons}">     <ListBox.ItemTemplate>         <DataTemplate>             <Border Child="{Binding Gender, Converter={StaticResource MyConverter}}"/>         </DataTemplate>     </ListBox.ItemTemplate> </ListBox> 

And the code behind:

public class MainViewModel : ViewModelBase {     public MainViewModel()     {         Persons = new List<Person> {new Person("Female"), new Person("Male")};     }      public List<Person> Persons { get; private set; } }  public class PersonConverter : IValueConverter {     private ResourceDictionary Items { get; set; }      public PersonConverterRes()     {         Items = new ResourceDictionary             {                 {"Male", new Canvas() {                                  Background = new SolidColorBrush(Colors.Blue),                                  Height = 100, Width = 100}},                 {"Female", new Canvas() {                                  Background = new SolidColorBrush(Colors.Magenta),                                  Height = 100, Width = 100}}             };     }      public object Convert(object value, Type targetType, object parameter,                           System.Globalization.CultureInfo culture)     {         return Items[value.ToString()];     }      ... }  public class Person {     public Person(String gender)     {         Gender = gender;     }      public String Gender { get; private set; } } 

But if I replace the ResourceDictionary with a plain Dictionary<String, UIElement> the binding works fine:

public class PersonConverter : IValueConverter {     private Dictionary<String, UIElement> Items { get; set; }      public PersonConverterRes()     {         Items = new Dictionary<String, UIElement>             {                 {"Male", new Canvas() {                                  Background = new SolidColorBrush(Colors.Blue),                                  Height = 100, Width = 100}},                 {"Female", new Canvas() {                                  Background = new SolidColorBrush(Colors.Magenta),                                  Height = 100, Width = 100}}             };     }      ... } 

Does anybody know what is causing this exception?

Note: I have tried this under WinRT as well. There, the code doesn't throw an exception, but the binding still doesn't work if I use a ResourceDictionary. I guess it's probably failing silently.

Answers & Comments...

Answer: 1

You can not use databinding to bind to the Child property of a Border since it is not a DependencyProperty. This is why your ResourceDictionary approach does not work.

Also, databinding in WPF/Silvelight/WinRT fails silently by design (it's a feature, and a very useful one if used correctly), so your guess would be right on that.

by : Kshitij Mehtahttp://stackoverflow.com/users/773885

Answer: 2

Don't do this.

More elegant to set a the Canvas.Background with trigger

<ListBox ItemsSource="{Binding Persons}">    <ListBox.ItemTemplate>        <DataTemplate>            <Border <!-- set properties --> >                <Canvas Height="100" Width="100">                   <Canvas.Style>                       <Style TargetType="Canvas">                         <Style.Triggers>                             <DataTrigger Binding={Binding Gender} Value="Male">                                   <Setter Property="Background" Value="Blue"/>                             </DataTrigger>                             <DataTrigger Binding={Binding Gender} Value="Female">                                   <Setter Property="Background" Value="Magenta"/>                             </DataTrigger>                         </Style.Triggers>                       </Style>                   </Canvas.Style>                </Canvas>            </Border>        </DataTemplate>    </ListBox.ItemTemplate> </ListBox> 
by : Miklós Baloghhttp://stackoverflow.com/users/946254




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog