none
how to dynamically re-position a child widow. (programmically)

    Question

  •  Hi.  I'm trying adjust where a child window is position on the user's screen.   For example, have a button in a child window that says "Move right", and when the user presses that button the child window will position it's self 300 px to the right.

    Is this possible in silverlight?  Thanks much.

    Tuesday, March 09, 2010 12:45 PM

Answers

  • In order to accomplish this, you need to access some of the controls that the ChildWindow is made up of.  To get a detailed description, you can take a look at the MSDN documentation here: http://msdn.microsoft.com/en-us/library/system.windows.controls.childwindow(VS.95).aspx

    If you want to move the window (in your example with a button click), here is the code that you will need:

    1                FrameworkElement root = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
    2                FrameworkElement contentRoot = (FrameworkElement)root.FindName("ContentRoot");
    3    
    4                Thickness mrg = contentRoot.Margin;
    5                mrg.Left += 300;
    6                contentRoot.Margin = mrg;
    7    
    

     The first line gets the root element of the control (in this case a Grid) using the VisualTreeHelper.  When then look for the ContentRoot, which is the outer container of the actual window.  The next couple of lines simply increase the left margin by 300px (thus moving the window to the right by 300px).

     Hope this helps.

    Tony

     

    Tuesday, March 09, 2010 3:05 PM

All replies

  • In order to accomplish this, you need to access some of the controls that the ChildWindow is made up of.  To get a detailed description, you can take a look at the MSDN documentation here: http://msdn.microsoft.com/en-us/library/system.windows.controls.childwindow(VS.95).aspx

    If you want to move the window (in your example with a button click), here is the code that you will need:

    1                FrameworkElement root = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
    2                FrameworkElement contentRoot = (FrameworkElement)root.FindName("ContentRoot");
    3    
    4                Thickness mrg = contentRoot.Margin;
    5                mrg.Left += 300;
    6                contentRoot.Margin = mrg;
    7    
    

     The first line gets the root element of the control (in this case a Grid) using the VisualTreeHelper.  When then look for the ContentRoot, which is the outer container of the actual window.  The next couple of lines simply increase the left margin by 300px (thus moving the window to the right by 300px).

     Hope this helps.

    Tony

     

    Tuesday, March 09, 2010 3:05 PM
  •  Tony, you the man!  It worked great.  that was a good reference too.  it's good to know that that documentation is there.

    Tuesday, March 09, 2010 3:32 PM
  •  Tony,  I'm running into a related problem again that I can't figure out.

     The button_click code above shifts the window to the right just fine when a button is pressed.  But in my particular situation it is not working.  Basically, I have a little child window that allow a user to open a file for importing purposes( a simple browse button is visible),  when the user has selected the file, I make visible a large portion of text for instruction.   This is causing my child window to appear off center to the right.

         I'm trying to fix this problem by moving the child window to the left after I make the instruction text visible, but It doesn't seem to work.  I figure it must have something to do with the open file dialog. I'm out of Ideas.  Any thoughts?   My code: 

            private void _Browse_Click(object sender, RoutedEventArgs e)
    {
    // Open file and get content
    string fileContent;
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.Filter = "Sources (*.txt;*.xml;*.csv)|*.txt;*.xml;*.csv";
    if ((bool)ofd.ShowDialog())
    {
    using (StreamReader reader = ofd.File.OpenText())
    {
    fileContent = reader.ReadToEnd();
    }
    }

    _InstructionsStackPannel.Visibility = Visibility.Visible;

    // Shift window...this has no effect.
    FrameworkElement root = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
    FrameworkElement contentRoot = (FrameworkElement)root.FindName("ContentRoot");
    Thickness mrg = contentRoot.Margin;
    mrg.Left += 20
    contentRoot.Margin = mrg;

    }
     
    Tuesday, March 16, 2010 11:15 AM
  • I just wanted to add my two cents in here since I've been working on this problem all day.

    What I have found is that when the size of the LayoutRoot changes, what is actually happening is that a new TranslateTransform gets added to the TransformGroup which then gets automagically "moved" to a new X (if the resize occurs on the width). If you handle the LayoutRoot_SizeChanged event you can look for a "5th" item in the TransformGroup and reset the X. Like so;

     

    private void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        var root = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
        var contentRoot = root.FindName("ContentRoot") as FrameworkElement;
        
        var group = contentRoot.RenderTransform as TransformGroup;
    
        if (group.Children.Count == 6)
        {
            var tf1 = group.Children[3] as TranslateTransform;
            var tf2 = group.Children[5] as TranslateTransform;
    
            // reset transform
            tf2.X = 0;
        }
    }
     
    Wednesday, March 31, 2010 6:01 PM
  •  Thanks Jonny,  I'm not sure how you found this answer but it works great!  I've been struggling with this and had given up.  I'm posting you as an answer on my other thread. http://forums.silverlight.net/forums/t/186375.aspx

    Tuesday, June 15, 2010 3:06 PM
  • I found a solution based on your code, that work with animation inside ChildWindow's.


    protected override void OnOpened()
    {
    this.LayoutUpdated += new EventHandler(OnChildWindowLayoutUpdated);
    base.OnOpened();
    }
    
    //in the ctor:
    this.Closed += new EventHandler(OnChildWindowClosed);
    
    void OnChildWindowClosed(object sender, EventArgs e)
    {
    this.LayoutUpdated -= OnChildWindowLayoutUpdated;
    }
    
    void OnChildWindowLayoutUpdated(object sender, EventArgs e)
    {
                var root = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
                if (root != null)
                {
                    var contentRoot = root.FindName("ContentRoot") as FrameworkElement;
    
                    if (contentRoot != null)
                    {
                        var group = contentRoot.RenderTransform as TransformGroup;
    
                        if (group != null)
                            if (group.Children.Count == 6)
                            {
                                var tf1 = group.Children[3] as TranslateTransform;
                                var tf2 = group.Children[5] as TranslateTransform;
    
                                if (tf1 != null)
                                {
                                    tf1.X = 0;
                                    tf1.Y = 0;
                                }
    
                                if (tf2 != null)
                                {
                                    tf2.X = 0;
                                    tf2.Y = 0;
                                }
                            }
                    }
                }
    }



    The code can be refactored to better performance. Please give a feedback.

     
    Tuesday, February 15, 2011 7:28 AM