NGI
NGI

Reputation: 902

New WPF Application B MainWindow starts with Size of the previously developed Application A MainWindow

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:

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

Upvotes: 0

Views: 80

Answers (1)

SilentStorm
SilentStorm

Reputation: 170

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.

Upvotes: 2

Related Questions