locked
Binding to a custom dependency property in a custom control RRS feed

  • Question

  • I created a custom control named ‘vRadioButtonGroup’ using a UserControl which in short, is a group of radio buttons.  I’ve created a custom DP in its codebehind called CheckedValue (int? data type).

    This DP works good when getting or setting it in csharp and also setting it in xaml like this:

    …  CheckedValue="5" />

    However, when binding in xaml nothing happens.  Here’s how I’m binding in xaml:

    CheckedValue="{Binding Pj_HardOrSoft}"  />

    As a test, I bound the same data property to a textblock and the binding did work as expected:
    <TextBlock  Grid.Row="9"  Grid.Column="1"  Text="{Binding Pj_HardOrSoft}" />


     

    Is there something special I need to do to the DP so it works with databinding?  Here's my DP:

    public static readonly DependencyProperty CheckedValueProperty = DependencyProperty.Register(
        "CheckedValue",
        typeof(int?),
        typeof(vRadioButtonGroup),
        new PropertyMetadata(null));
    
    public int? CheckedValue
    {
        get 
        { 
            //Loop through the collection of radio buttons and get the value of the checked one.
            foreach (RadioButtonItem item in _list)
            {
                if (item.ButtonItem.IsChecked == true)
                {
                    return item.ItemValue;
                }
            }
            return null;
        }
        set
        {
            //Loop through the collection of radio buttons and check the correct one
            foreach (RadioButtonItem item in _list)
            {
                if (item.ItemValue == value)
                {
                    item.ButtonItem.IsChecked = true;
                    return;
                }
                else
                {
                    item.ButtonItem.IsChecked = false;
                }
            }
        }
    }
    



     

    Can someone please advise me what I need to do to make binding in xaml work?

    Thank you.

     

    Monday, June 27, 2011 6:26 PM

Answers

  • public int? CheckedValue
    {
        get { return (int?)GetValue(CheckedValueProperty); }
        set { SetValue(CheckedValueProperty, value); }
    }
    
    public static readonly DependencyProperty CheckedValueProperty =
        DependencyProperty.Register(
            "CheckedValue",
            typeof(int?),
            typeof(TemplatedControl1),
            new PropertyMetadata(OnCheckedValueChanged));
    
    private static void OnCheckedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = (TemplatedControl1)d;
        foreach (var item in sender._list)
        {
            item.ButtonItem.IsChecked = item.ItemValue == sender.CheckedValue;
        }
    }

    http://msdn.microsoft.com/en-us/library/cc903933(v=vs.95).aspx#checklist

    See "XAML Loading and Dependency Properties".

    Tuesday, June 28, 2011 5:36 PM

All replies

  • This is something u can try

    public int? CheckedValue
    {
        get 
        { 
           
            return (int?)GetValue(CheckedValueProperty);
        }
        set
        {
           SetValue(CheckedValueProperty, value);
            
        }
    }

    And while binding use a converter to do the things you were doing before.

    Monday, June 27, 2011 7:19 PM
  • Here are few links from my blog. here I have created dependency property and bind it in xaml and it works fine

    http://asimsajjad.blogspot.com/2011/01/post-comments-using-silverlight.html

    what you have to do is to have separate properties for get and set and it will work fine.

    Monday, June 27, 2011 8:48 PM
  • Thanks Samirkopal.  I dont follow how to use the converter in this case.  If I write the setter an normal like this:

    SetValue(CheckedValueProperty, value);

    and then follow with some code that does something with the new value like this:

    //Loop through the collection of radio buttons and check the correct one
    foreach (RadioButtonItem item in _list)
    {
        if (item.ItemValue == value)
        {
            item.ButtonItem.IsChecked = true;
            return;
        }
        else
        {
            item.ButtonItem.IsChecked = false;
        }
    }

    why wont this work.  Actually, I'm putting a break point in the setter and its never firing which tells me the biding isnt even taking place.

    Monday, June 27, 2011 11:08 PM
  • Try setting the Mode of the binding:

    CheckedValue={Binding Pj_HardOrSoft, Mode=TwoWay}


     

    Tuesday, June 28, 2011 12:32 AM
  • First of all dependency property , every control which has the dependency property has its own copy mean if you change to the value of the dependency property then it only value of that control dependency property change. You can use GetValue, SetValue in you get/set.and try to set binding mode to two ways

    Tuesday, June 28, 2011 12:52 AM
  • One thing that you can try to see if your binding syntax is correct is to try binding from the code behind.  If that works you will need to check the syntax in XAML. If not, please paste your code behind and I can take a look.

    Tuesday, June 28, 2011 12:50 PM
  • Thanks to all who have responded so far.  First of all, this is being used in a read only sceen so I dont think i need 2 way binding, but i tried that anyway with no luck. I think my binding syntax is OK becuase this works:

    <TextBlock  Grid.Row="9"  Grid.Column="1"  Text="{Binding Pj_HardOrSoft}" />

    but this does not:

    <vRbg:vRadioButtonGroup Grid.Row="9"   Grid.Column="1"  Name="Pj_HardOrSoft" ButtonList="1,Hard;2,Soft"  CheckedValue="{Binding Pj_HardOrSoft}"  />


    I can set the value in the control using c# and the correct radio button becomes selected as expetced:

    Pj_HardOrSoft.CheckedValue = objB.Pj_HardOrSoft;

    but when binding in xaml, nothing happens.  Once again, here's the DP property listed below.  You can see that it uses GetValue and SetValue as it should, and also runs the additional code in the setter to check the correct radio button.  By the way, this DP executes correctly when setting the value from the line of C# above:

    public int? CheckedValue
    {
        get
        {
            return (int?)GetValue(CheckedValueProperty);
            ////Loop through the collection of radio buttons and get the value of the checked one.
            //foreach (RadioButtonItem item in _list)
            //{
            //    if (item.ButtonItem.IsChecked == true)
            //    {
            //        return item.ItemValue;
            //    }
            //}
            //return null;
        }
        set
        {
            SetValue(CheckedValueProperty, value);
    
            //Loop through the collection of radio buttons and check the correct one
            foreach (RadioButtonItem item in _list)
            {
                if (item.ItemValue == value)
                {
                    item.ButtonItem.IsChecked = true;
                    return;
                }
                else
                {
                    item.ButtonItem.IsChecked = false;
                }
            }
        }
    }

    So I think the binding is not setting a value to the DP in the xaml binding shown in the 2nd line of code in this post.  Would anyone like to see a sample project with this. This will be a handy control for anyone needing to use radio buttons once it works correct becuase it simplfies the logic and code needed.


    Tuesday, June 28, 2011 4:06 PM
  • try CheckedValue ="{Binding objB.Pj_HardOrSoft}"

    Tuesday, June 28, 2011 4:30 PM
  • That didnt work either.  objB is just the business object variable used in a UI's code behind.  Would you like to see a small sample project?  if so, how can i send it to you - i dont see a way to attach files to posts.

    Tuesday, June 28, 2011 5:34 PM
  • public int? CheckedValue
    {
        get { return (int?)GetValue(CheckedValueProperty); }
        set { SetValue(CheckedValueProperty, value); }
    }
    
    public static readonly DependencyProperty CheckedValueProperty =
        DependencyProperty.Register(
            "CheckedValue",
            typeof(int?),
            typeof(TemplatedControl1),
            new PropertyMetadata(OnCheckedValueChanged));
    
    private static void OnCheckedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = (TemplatedControl1)d;
        foreach (var item in sender._list)
        {
            item.ButtonItem.IsChecked = item.ItemValue == sender.CheckedValue;
        }
    }

    http://msdn.microsoft.com/en-us/library/cc903933(v=vs.95).aspx#checklist

    See "XAML Loading and Dependency Properties".

    Tuesday, June 28, 2011 5:36 PM
  • That totaly worked.  thanks for the link which helps me understand why it wasnt working, and also thank you for re-writing my code and cleaning it up a bit!

    Tuesday, June 28, 2011 8:06 PM