2

Sorry for very long title of question but I had no idea how to make it shorter.

I have SettingsView Window with content control:

<Window x:Class="IsoMan.UI.Settings.Views.SettingsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="SettingsView" WindowStartupLocation="CenterOwner"
    SizeToContent="WidthAndHeight">
    <ContentControl Name="ContentControl"/>
</Window>

Here in code-behind I am setting content of ContentControl. Here I simplified it a lot, normally it is set dynamically through binding so I never now what type of UserControl is currently set as Content. (but always UserControl)

public partial class SettingsView : Window
{
    public SettingsView()
    {
        InitializeComponent();   
        ContentControl.Content = new UserSettingsView();
    }
}

Here is my UserSettingsView.xaml, the control that is a child of SettingsView:

<UserControl x:Class="IsoMan.UI.Settings.UserSettings.Views.UserSettingsView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        MinHeight="400" MinWidth="700">
    <DataGrid ItemsSource="{Binding UsersList}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding FirstName}" Width="*"/>
        </DataGrid.Columns>
    </DataGrid>
</UserControl>

And here is my problem.

I have Window SizeToContent set to WidthAndHeight, because I want it's size to adjust to child control size (in this case UserSettingsView).

UserSettingsView has MinWidth/MinHeight set as I want user to not be able to make it smaller (buttons/grid presentation). This control has grid with one column which width is "*". I want it to take all available space.

What happens now:

After showing SettingsView it's width is MAX width of my screen. I think that it is cased by the fact, that grid's column's width in UserSettingsView is set to "*".

What I want to achieve:

After showing SettingsView it's width should be MinWidth of UserSettingsView. Also, when user try to resize SettingsView window, child control UserSettingsView should be resized also.

GrzegorzM
  • 842
  • 8
  • 19

2 Answers2

1

Bind host window's MinWidth and MinHeight properties when you set its Content. In window xaml remove SizeToContent="WidthAndHeight", instead on child ContentControl do HorizontalAlignment="Stretch", VerticalAlignment="Stretch" and in code behind when actual content is being set use:

public partial class SettingsView : Window
{
    public SettingsView()
    {
        InitializeComponent();
        var _content = new UserSettingsView();
        ContentControl.Content = _content;
        this.MinWidth = _content.MinWidth;
        this.MinHeight=_content.MinHeight;
        this.Width=this.MinWidth;
        this.Height=this.MinHeight;
    }
}
bamanow
  • 93
  • 7
  • It is not possible to do it as you suggested, since my ContentControl's Content is bound to some observable property, as I described in my question. I do not know in code behind when Content is changed and to what. – GrzegorzM Dec 01 '15 at 08:41
  • You do have access to host window class don't you? Observe content property changed, cast new value to UserControl. After that use code above. – bamanow Dec 01 '15 at 08:45
1

Ok, so I fixed my issue by providing the ability to ContentControl to notify when it's Content changed.

ContentControlWithNotification.cs:

public class ContentControlWithNotification : ContentControl
{
    static ContentControlWithNotification()
    {
        ContentProperty.OverrideMetadata(typeof(ContentControlWithNotification), new FrameworkPropertyMetadata(OnContentChanged));
    }

    private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var mcc = d as ContentControlWithNotification;

        if (mcc.ContentChanged != null)
        {
            var args = new DependencyPropertyChangedEventArgs(ContentProperty, e.OldValue, e.NewValue);
            mcc.ContentChanged(mcc, args);
        }
    }

    public event DependencyPropertyChangedEventHandler ContentChanged;
}

Then I attached event handler to ContentChanged event in XAML:

<l:ContentControlWithNotification x:Name="ActiveItem" ContentChanged="ActiveItem_OnContentChanged"/>

and here is my handler implementation:

public partial class SettingsView : Window
{
    public SettingsView()
    {
        InitializeComponent();
    }

    private void ActiveItem_OnContentChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var newUserControl = (UserControl)e.NewValue;
        MinWidth = newUserControl.MinWidth;
        MinHeight = newUserControl.MinHeight;
        Width = MinWidth;
        Height = MinHeight;
    }
}

Now it works as I expected

GrzegorzM
  • 842
  • 8
  • 19