locked
Automatic resizing of User Control after adding content programmatically RRS feed

  • Question

  • I have a user control (UC) that is placed on a Canvas at runtime. The XAMl looks like this:

    <UserControl x:Class="GVWpfRenderingEngineStandard.RadioButtonsUC" 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:local="clr-namespace:GVWpfRenderingEngineStandard"
                 mc:Ignorable="d" d:DesignHeight="70" d:DesignWidth="150">
    
      <Border Name="Br_Frame" BorderThickness="5" CornerRadius="4">
        <DockPanel Background="{Binding ChValBackground}">
          <GroupBox Header="{Binding ChannelName}" Margin="3">
            <WrapPanel Name="WP_Buttons" Orientation="Horizontal"/>
          </GroupBox>
        </DockPanel>
      </Border>
    </UserControl>

    The UC starts very small as there is nothing but an empty GroupBox on it (with a default header). After some user configuration, a number of RadioButtons are added in code (C#) to the WrapPanel and the dependency property bound to the WrapPanel gets a new value - nothing else:

    EnumRB = new Dictionary<int, RadioButton>();
    foreach(KeyValuePair<int, string> EV_KVP in ChannelRef.GetUnderlyingType())
    {
      EnumRB[EV_KVP.Key] = new RadioButton();
      EnumRB[EV_KVP.Key].Content = EV_KVP.Value;  // For the header content
      EnumRB[EV_KVP.Key].Tag = EV_KVP.Key; // For the enumeration value
      EnumRB[EV_KVP.Key].Checked +=new RoutedEventHandler(OnValueChange);
      EnumRB[EV_KVP.Key].Margin = new Thickness(8);
      WP_Buttons.Children.Add(EnumRB[EV_KVP.Key]);
    }

    The size of the UC does not change in response to that operation. If the user resized the UC, the content is revealed and it looks as expected. However, I'd like my UC to automatically resize itself after the content has been added. What is an elegant way for achieving that? I'd like a solution in the XAML but I'd resort to code-behind, if necessary.

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.


    • Edited by Kamen Tuesday, August 20, 2013 2:19 AM
    Tuesday, August 20, 2013 2:19 AM

Answers

  • Immediately after I posted the previous message, I found the problem. And, as I thought, it wouldn't have been something that I could have hoped to get much help with.

    It started with my statement that I hadn't inspected all elements when it dawned on me that I hadn't looked at the most-likely culprit: the custom control that hosted the user control. Needless to say, its width and height were not NaN, which would not be surprising since it is user-resizable, but that was the case (both were equal to zero) even when it is first created. Then, I found the problem - I had recently added an initialization in the code for the creation of the custom control specifically for some third-party libraries, whose controls experienced problems unless their container's width and height were initialized. You win some, then you lose some...

    All I had to do to fix it is reset the containing custom control's width and height to NaN before initialization and it now works fine, even when editing the content.

    I guess the morale here is: if it is not resizing properly, then just look up the tree and find a container whose size is fixed.

    I love WPF for its power but, man, is it tough to debug! (with all the declarative code)

    Kamen

    P.S. Magnus, I would like to somehow reward you for your efforts; in case (like to some other posters here) it is very important to you to be credited with answers, feel free to post something conclusive and I'll mark it as an answer. Otherwise I should probably convert this to a discussion since I don't see much usefulness of this thread to others searching for answers to their own problems. You do have my gratitude either way.
    K.


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    • Marked as answer by Kamen Wednesday, August 21, 2013 3:47 PM
    Tuesday, August 20, 2013 8:30 PM

All replies

  • Could you please post some more code for us to be able to reproduce the issue? In the below example, an instance of the user control is added to a Canvas in the MainWindow at runtime and when you click the button in the UserControl some controls are added to the Canvas inside the UserControl, causing it to resize itself automatically:

    Window:

    public MainWindow() {
          InitializeComponent();
          this.Loaded += MainWindow_Loaded;
      }
        void MainWindow_Loaded(object sender, RoutedEventArgs e) {
          MyUserControl control = new MyUserControl();
          mainCanvas.Children.Add(control);
        }

    UserControl:

    <UserControl x:Class="WpfApplication3.MyUserControl"
                 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" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
      <Border Name="Br_Frame" BorderThickness="5" CornerRadius="4">
        <StackPanel>
          <GroupBox Header="{Binding ChannelName}" Margin="3">
            <WrapPanel Name="WP_Buttons" Orientation="Horizontal"/>
          </GroupBox>
          <Button Content="click" Click="Button_Click" />
        </StackPanel>
      </Border>
    </UserControl>

        private void Button_Click(object sender, RoutedEventArgs e) {
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          WP_Buttons.Children.Add(new RadioButton());
          Image img = new Image();
          BitmapImage logo = new BitmapImage();
          logo.BeginInit();
          logo.UriSource = new Uri("pack://application:,,,/WpfApplication3;component/pic2.jpeg");
          logo.EndInit();
          img.Source = logo;
          WP_Buttons.Children.Add(img);
        }

    Tuesday, August 20, 2013 1:38 PM
  • Hello, Magnus,

    Thank you, very much, for your input. I really appreciate your taking the time to try and reproduce the problem. It might turn out to be too difficult to resolve, though. The problem is that this code is part of a very complex UI where that user control is added in code to a custom control that, in its turn, is added dynamically to another control, and so on, for multiple layers of templated controls, that are manipulated at runtime by the user.

    I spent the last few hours trying to reproduce it in a separate project because the actual production project is a huge VS solution with nearly a dozen projects, forming multiple dynamically-linked libraries, all working together to produce the interface. The worst part is that I had this functionality (i.e., the automatic resizing) and then lost it - it must have been some global change that has affected it, although it wasn't perfect from the beginning - the automatic resizing would only work the first time content is added, but it would not work after it is changed (edited). This probably has something to do with initialization but I have no idea where and how. I have checked with the debugger that all widths and heights of the elements in the tree (at least the ones I could think of to look at) were equal to NaN and the ActualWidths and -Heights were some numbers, but not what it would take to not hide the content. It must be the parent custom control, which is user-resizable - once the user resizes it, it stays that way. I'll look a little deeper in there.

    This appears to be some quirk related to my specific code and not a simple WPF condition, so I'll understand if it does not merit further attention, especially since it isn't that important to my project (the component might be replaced with a better one in the future, or I could do the resizing in code). Thank you for your effort, either way.

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Tuesday, August 20, 2013 7:54 PM
  • Immediately after I posted the previous message, I found the problem. And, as I thought, it wouldn't have been something that I could have hoped to get much help with.

    It started with my statement that I hadn't inspected all elements when it dawned on me that I hadn't looked at the most-likely culprit: the custom control that hosted the user control. Needless to say, its width and height were not NaN, which would not be surprising since it is user-resizable, but that was the case (both were equal to zero) even when it is first created. Then, I found the problem - I had recently added an initialization in the code for the creation of the custom control specifically for some third-party libraries, whose controls experienced problems unless their container's width and height were initialized. You win some, then you lose some...

    All I had to do to fix it is reset the containing custom control's width and height to NaN before initialization and it now works fine, even when editing the content.

    I guess the morale here is: if it is not resizing properly, then just look up the tree and find a container whose size is fixed.

    I love WPF for its power but, man, is it tough to debug! (with all the declarative code)

    Kamen

    P.S. Magnus, I would like to somehow reward you for your efforts; in case (like to some other posters here) it is very important to you to be credited with answers, feel free to post something conclusive and I'll mark it as an answer. Otherwise I should probably convert this to a discussion since I don't see much usefulness of this thread to others searching for answers to their own problems. You do have my gratitude either way.
    K.


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    • Marked as answer by Kamen Wednesday, August 21, 2013 3:47 PM
    Tuesday, August 20, 2013 8:30 PM