2

I have custom control with nested (custom) control. I would like to get the property from the nested control and pass it to converter of main control. Here is my code:

<Button.IsEnabled>
  <MultiBinding Converter="{x:Static app:MainControl.CanExcludeConverter}">
    <Binding Path="PageIndex" ElementName="nav_pane"/>
    <Binding Path="History" />
  </MultiBinding>
</Button.IsEnabled>

The second parameter is passed correctly, but the first one is not -- no matter what I do I get only DependencyProperty.UnsetValue. Firstly I had PageIndex as just property with notifiers, then I made it dependency property, then I tried several ways to set the Binding -- no success at all.

"nav_pane" is the name of my custom control which is nested in MainControl. PageIndex is dependency property of NavPane.

What am I missing?

Edits

1

Longer example. MainControl actually consists of NavPane and that's all :-) Thanks to the dependency properties set in NavPane as "slots" I can add new controls within frame (rectangle) of NavPane. So this is how it starts:

<UserControl x:Class="Worture.MainControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:app="clr-namespace:Worture"
             mc:Ignorable="d" 
             Height="Auto" Width="320" 
             BorderThickness="2" BorderBrush="Navy"  
             MouseEnter="UserControl_MouseEnter"
             IsVisibleChanged="UserControl_IsVisibleChanged"
             Loaded="UserControl_Loaded">
    <Grid Margin="4,0,4,4">
        <app:NavPane x:Name="nav_pane" 
                      OnNavigation="UpdateNavPane">
            <app:NavPane.UpperSlot>
                <Button Margin="4,0,0,0">
                    <StackPanel Orientation="Horizontal">
                        <app:AutoGreyableImage Source="/Worture;component/Images/plus.png"  Width="24" Height="24"/>
                    </StackPanel>
                    <Button.IsEnabled>
                     ...

The rest is above.

2

Dependy property in NavPane.

    public static readonly DependencyProperty PageIndexProperty =
      DependencyProperty.Register(NameOf.Get((NavPane dlg) => dlg.PageIndex),
      typeof(int?),
      typeof(NavPane),
      new UIPropertyMetadata(null));
    
    public int? PageIndex
    {
        get { return (int?)GetValue(PageIndexProperty); }
        set { SetValue(PageIndexProperty, value); }
    }

NameOf is a nice class found on SO, which gets name of property, field, etc. Thanks to it, I avoid magical numbers and I am better suited for obfuscation.

3

I get UnsetValue as input argument in converter. PageIndex is set on various occasions (it depends on user too). But to focus, I set it (right now) to null as the first line in constructor. So theoretically I should get such argument -- null (as "int?").

Community
  • 1
  • 1
greenoldman
  • 16,895
  • 26
  • 119
  • 185
  • What binding errors do you get in the Output window? ([Debug Databindings](http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx)) – H.B. Jun 01 '11 at 16:46
  • @H.B., none (related to those controls, there a few errors but for completely different windows/controls). – greenoldman Jun 01 '11 at 17:08
  • Could you give us a little more of your XAML showing the nesting of the controls? – Tim Jun 01 '11 at 17:39
  • Where are you getting this 'unsetvalue'? Inside of the converter code, or as the result of the converter? Better yet, at what point is the 'PageIndex' set on nav_pane? – A.R. Jun 01 '11 at 18:22
  • @A.R. what do you mean by "set"? It is Nullable sometimes it is null, sometimes it has real value, but I should get Nullable not DependencyProperty (type, and besides it is always UnsetValue). Just in case, I will post this property as well. – greenoldman Jun 01 '11 at 18:26
  • Are you only seeing this issue when obfuscating your code? Your `Path="PageIndex"` would not be valid if you are. – CodeNaked Jun 01 '11 at 18:40
  • @CodeNaked, I am **NOT** obfuscating my code of course -- I **will** obfuscate code as next step, when everything works in "normal" mode. Obfuscation is out of scope of this problem. – greenoldman Jun 01 '11 at 18:44
  • @macias. By set, I mean assigned to. We can't ever see how it is being used so it is hard to say why it is always coming up 'unset' – A.R. Jun 01 '11 at 20:37
  • @A.R. in constructor of NavPane is simply "PageIndex = null". Btw. I should get null Nullable not UnsetValue of DependencyProperty, it rather shows, that the dependency property is unset, not value which it holds. The code of DP is shown in edit 2. – greenoldman Jun 02 '11 at 04:14

1 Answers1

1

Chances are you are not properly adding the Button as a logical child of the NavPane. Basically, you should call AddLogicalChild on your NavPane for each item added to your UpperSlot collection. You should also call RemoveLogicalChild for anything removed from your collection.

Finally, you need to override LogicalChildren in NavPane and include the items in your collection (in addition to anything returned by the base version).

If UpperSlot is not a collection, then you just need to add/remove the single element that it refers to.

Kent Boogaart has a good write up of this here. And more information on ElementName resolution can be found here and here.

Community
  • 1
  • 1
CodeNaked
  • 40,753
  • 6
  • 122
  • 148
  • Thank you, but this is not the problem 100% sure. First of all it is just a control, I should be able to bind it (from unrelated widget as well). As for testing, I moved this button outside the NavPane, same result. – greenoldman Jun 01 '11 at 19:38
  • @macias - If you can upload a complete sample somewhere, it would be much easier to debug as there must be something else going on :-) – CodeNaked Jun 01 '11 at 19:39
  • scrap my initial comment -- I didn't wait for all breakpoints to evaluate. It is indeed something wrong with placement the button within my custom control. When I moved it to be at equal level in hierarchy, it worked. I don't understand, why XAML doesn't do all the magic, I will read all the stuff ASAP. – greenoldman Jun 02 '11 at 17:54
  • I chose another solution -- fixing this is overkill for me, and it "smells" odd, it should be XAML task, not mine. I'll set a receiver on PageIndex change, and add a property for MainControl which I can bind with no problem. The amount of code (comparing to theoretically fixed version) is way less. Thanks a lot for your help, I wouldn't find it. – greenoldman Jun 02 '11 at 18:13