none
Binding to a window property

    Question

  • I'm having touble getting binding to work programmatically. The following XAML works and displays the correct values/allows me to change things etc.:

     

    Code Snippet

    <Window x:Class="Control_Binding_Tests.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="300" Width="300">

    <Grid>

    <Grid.RowDefinitions>

    <RowDefinition />

    <RowDefinition />

    <RowDefinition />

    <RowDefinition />

    </< FONT>Grid.RowDefinitions>

    <TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Title}" Grid.Row="0" />

    <TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Width}" Grid.Row="1" />

    <TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Height, Mode=OneWayToSource}" Grid.Row="2" />

    <Line Grid.Row="3" Stroke="Red" StrokeThickness="5" X1="0" X2="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Width}" Y1="0" Y2="0" />

    </< FONT>Grid>

    </< FONT>Window>

     

     

    But when I cut this out:

    Code Snippet

     

    {Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Height, Mode=OneWayToSource}

     

     

    And put it in C# here:

     

    Code Snippet

    Binding binding = new Binding("{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=Height}");

    Line l = makeLine((int)ms_indent + (i * (int)ScaleLength), 0, (int)ms_indent + (i * (int)ScaleLength), 250);

    l.SetBinding(Line.Y2Property, binding);

     

    The line's Y2 property is initially set to 250 (which is correct), but as soon as the l.SetBinding() line is executed it turns to zero. I can feel I'm close - where's my problem? Smile. BTW: makeLine is just a wee function that returns a line rather than cluttering up the rest of the code.

     

    Regards,

    Sloan

     

    Wednesday, August 08, 2007 3:38 PM

Answers

  • That code is effectively what RelativeSource does.  I assume you've tried that as well:

    binding = new Binding("Height");

    binding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Window), 1);

    l.SetBinding(Y2Property, binding);

     

    This binding isn't evaluated until the next layout pass, to give WPF (and your app) a chance to build the tree:  attaching the new Line to a parent somewhere, etc.  You can't expect line.Y2 to have the correct value immediately, but by the time it renders it should be OK.

     

    If this (or your getWindow) still doesn't work, it's probably because the path from your Line to the Window isn't a straightforward parent/child one.  Can you tell us more about what lies between the Line and the Window?

     

    Thursday, August 09, 2007 8:26 PM

All replies


  • hi there

    when doing data binding programitically the bind is a bit different. You need to specify the Property Name only in the property path... let me give you an example

    Binding b = new Binding("Height");

    b.Source = windowInstance;

    l.SetBinding(Line.Y2Property, b);

    hope this helps
    Wednesday, August 08, 2007 4:44 PM
  • Hi Marlon,

     

    Yep - I thought it was that <grin>. The problem is that the code's inside a user control, so I don't *know* what window contains the control. If I could find a way to grab the window that would be OK. I've tried this bit of code (it doesn't work) but it was a valiant attempt to try and grab the window from the tree:

     

    Code Snippet

    private object getWindow(object _obj)

    {

    if (_obj is FrameworkElement)

    {

    FrameworkElement fe = (FrameworkElement)_obj;

    if (fe.Parent != null)

    return getWindow(fe.Parent);

    }

    else

    if (_obj is Window)

    return _obj;

    return null;

    }

     

     

    It would have been nice if that had work'd! Wink Mind you, it would be even nicer if there was a frameworkElement.getTopLevelContainerObject() method ...

     

    Cheers,

    Sloan

    Thursday, August 09, 2007 7:57 AM
  • That code is effectively what RelativeSource does.  I assume you've tried that as well:

    binding = new Binding("Height");

    binding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Window), 1);

    l.SetBinding(Y2Property, binding);

     

    This binding isn't evaluated until the next layout pass, to give WPF (and your app) a chance to build the tree:  attaching the new Line to a parent somewhere, etc.  You can't expect line.Y2 to have the correct value immediately, but by the time it renders it should be OK.

     

    If this (or your getWindow) still doesn't work, it's probably because the path from your Line to the Window isn't a straightforward parent/child one.  Can you tell us more about what lies between the Line and the Window?

     

    Thursday, August 09, 2007 8:26 PM
  • Sam,

    Perfect! I hadn't tried that... <blush>. It's all this technology that WPF throws at you, it's hard to know what method/property/event/etc. to use at times.

     

    Thanks again!

    Sloan

     

    Friday, August 10, 2007 7:22 AM