0

I developed last week an Application A that had a "wide" MainWaindow (more than 1400 pixels)

I am at the present time starting the development of a new Application B (which looks for running Excel instances)

So I have a view that contains a DataGrid which has its Width property to Auto (Designer picture below). Everything's fine

enter image description here

Then I insert it to the MainWindow (here Designer picture)

Datagrid View Designer picture

It is not what exactly what I expected but I still have to make some research in SO questions like this one wpf-datagrid-why-the-extra-column (the answer tells it is not an extra column it is a supplementary width...)

Then I run this Application B. Wonder: I get an even wider window.

enter image description here

The exact question I want to expose here is:

  • Why do I get at runtime of Application B the same width as the one of last week's Application A ?

I do not believe in coincidence (I did also no copy/paste between the 2 applications). Where is it back-up ? I already read posts about styles (default style, style dedicated to window not applied to the inheriting MainWindow ... )

Any (real) rationale reading about WPF also welcome !

EDIT: Add code (I first did not wanted to show code to concentrate on the question. Because there are "thousand" places where you can set a Width... with effect or not)

    <UserControl ...
             d:DataContext="{d:DesignInstance {x:Type vm_nmspc:MainWindowVm}, IsDesignTimeCreatable=True}">


    <UserControl.Resources>
        <Style TargetType="DataGridRow">
            <Setter Property="Width" Value="Auto"/>
            ...
        </Style>
    </UserControl.Resources>

    <Grid>
        <DataGrid ItemsSource="{Binding OpenExcelColl}" AutoGenerateColumns="False" AlternationCount="{Binding OpenExcelColl.Count}" 
                  VirtualizingPanel.IsVirtualizing="False" CanUserAddRows="False" SelectedItem="{Binding SelectedExcelObject}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
                <DataGridTextColumn Header="Path" Binding="{Binding CompletePath}" IsReadOnly="True"/>
                <DataGridTextColumn Header="Type" Binding="{Binding ExtType}" IsReadOnly="True"/>
            </DataGrid.Columns>
            ...
        </DataGrid>
    </Grid>

</UserControl>

And the MainWindow.xaml (Note that no Width had been given, hoping that the MainWindow would fit automatically. Width="Auto" did not work)

<Window ...
    DataContext="{DynamicResource ResourceKey=MyVM}"
    mc:Ignorable="d"
    Title="MainWindow" Height="350"
    SizeToContent="Width">   <<------- Line added to "workaround/solve" the problem


    <Window.Resources>
        <vm_nmspc:MainWindowVm x:Key="MyVM"/>
    </Window.Resources>

    <Grid>
        <views:AllExcelObjDataGrid DataContext="{Binding}"/>
    </Grid>
</Window>

After SizeToContent="Width"

enter image description here

Community
  • 1
  • 1
NGI
  • 852
  • 1
  • 12
  • 31
  • I think I found a start of answer [why-are-my-wpf-window-sizes-defaulting-to-be-huge](http://stackoverflow.com/questions/3146106/), at least by adding *SizeToContent="Width"* to the Window property. – NGI Mar 09 '17 at 14:52
  • Post some Xaml code, this probably happens because you set width to auto so it will take whatever space it can get from its parent. In your Datagrid set `ColumnWidth="*" ` to equally divide remaining space among your columns. – SilentStorm Mar 09 '17 at 15:24
  • What exactly is your question? What are the expected results? – mm8 Mar 09 '17 at 16:27
  • @mm8 It is quite a long (but illustrated) question, so that I put a bullet to mark the end of the first post (before adding xaml): Why Application B takes the size that was the one of Application A ? I do not know if there is an ultimate documentation explaining all of these mechanisms. The link to the SO question I put in my (own) first comment leads to other several questions and links like the one from microsoft [WPF Windows Overview](https://msdn.microsoft.com/en-us/library/ms748948.aspx) – NGI Mar 09 '17 at 22:10

1 Answers1

2

The problem here is that you set width to auto, meaning it will take all available space from its parent.

If I look up the visual tree no other width has been set, so your datagrid will stretch over the entire application.

The reason application B takes the exact same space in debugging as application A is because Windows actually thinks these are the same applications because they are started both with vshost.

Now, you can set your width on the parent, I prefer something like this:

<Window...
Width="1366"
MinWidth="{Binding Source={x:Static SystemParameters.FullPrimaryScreenWidth}, Converter={StaticResource ScreenSizeConverter}}"

your datagrid will still stretch over the entire application, remove the width=auto setter if you want to create space on the left or right to place some extra controls.

Now, either apply a static width to your datagrid or use the Grid you wrap your datagrid in and divide in columns using a dynamic width. example:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200"/>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <DataGrid Grid.Column="0" ItemsSource="{Binding OpenExcelColl}" AutoGenerateColumns="False" AlternationCount="{Binding OpenExcelColl.Count}" 
              VirtualizingPanel.IsVirtualizing="False" CanUserAddRows="False" SelectedItem="{Binding SelectedExcelObject}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Path" Binding="{Binding CompletePath}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Type" Binding="{Binding ExtType}" IsReadOnly="True"/>
        </DataGrid.Columns>
        ...
    </DataGrid>

    <StackPanel Grid.Column="1">
        <!--  Additional controls here -->
    </StackPanel>
</Grid>

if you still have a little white space you want to get rid off use

<DataGrid ColumnWidth="*" ...

This will divide remaining space among your columns.

EDIT

You do not really need the sreensizeconverter, you can set a static number, it is a quick and dirty implementation to set the parent window minwidth, for your convenience:

public class ScreenSizeConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value.GetType() == typeof(double))
        {
            return (((double)value / 4) * 3);
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

in App.xaml (Window.Resources should work but I think you are forgetting ResourceDictionary, that is why it won't compile, I prefer App.xaml because now you only need to import it once and you use across all windows and usercontrols):

<Application x:Class="MecamApplication.Client.App" 
         ...
         xmlns:Converters="clr-namespace:MecamApplication.Core.Converters;assembly=MecamApplication.Core">


<Application.Resources>
    <ResourceDictionary>
        <Converters:ScreenSizeConverter x:Key="ScreenSizeConverter"/>
    </ResourceDictionary>
</Application.Resources>

Still, you could just set minwidth="500" and width="950" and you would achieve the same, I forgot to clean that part out.

SilentStorm
  • 172
  • 1
  • 1
  • 12
  • Thanks for your answer. At early stage of development (of what will be only an internal application, not a AAA commercial stuff) I had rather to have everything autosized (I will fix some fixedsizes later). Dimension of windows is a rather difficult subject (how many relevant combinations can I get with 200, 200*, Auto, HorizontalAlignment="Stretch" ... at multiple levels of the visual tree...) That's why I was also looking for "rational" / logic behind all of this. Still have to fully test all your options. – NGI Mar 09 '17 at 21:49
  • Could you show a little bit more of your XAML ? I have a small problem. I defined a converter class that is instanciated in the but then I get an exception because *StaticResource ScreenSizeConverter* line is before ** line and the converter is not created at that time. I am reading posts about that subject like [wpf-window-title-from-static-resource](http://stackoverflow.com/questions/19840044)... DynamicResource seems not to be usable due to the binding... – NGI Mar 15 '17 at 14:28
  • I manage to solve the problem of my last comment by declaring below the resources the MinWidth property ... . Thanks for your Edit ( I thought I would have been notified but I have seen nothing at the present time ) – NGI Mar 15 '17 at 16:11