新的WPF应用程序B MainWindow以先前开发的应用程序A MainWindow

时间:2017-03-09 14:36:24

标签: c# wpf

我上周开发了一个具有“宽”MainWaindow(超过1400像素)的应用程序A

我目前正在开始开发新的应用程序B(寻找运行的Excel实例)

所以我有一个包含DataGrid的视图,其Width属性为Auto(下图设计师图片)。一切都很好

enter image description here

然后我将它插入到MainWindow(这里是Designer画面)

Datagrid View Designer picture

这不是我所期望的,但我仍然需要在这样的问题中进行一些研究wpf-datagrid-why-the-extra-column(答案告诉它不是一个额外的列,它是一个补充宽度......)< / p>

然后我运行此应用程序B。不知道:我的窗户更宽了。

enter image description here

我想在这里公开的确切问题是:

  • 为什么我在应用程序B的运行时获得与上周的应用程序A相同的宽度?

我不相信巧合(我在2个应用程序之间也没有复制/粘贴)。备份在哪里? 我已经阅读了关于样式的帖子(默认样式,专用于窗口的样式未应用于继承的MainWindow ...)

关于WPF的任何(真实的)理论阅读也欢迎!

编辑:添加代码(我首先不想显示代码专注于问题。因为有“千”个地方你可以设置宽度......有效与否)

    <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>

和MainWindow.xaml(请注意,没有给出Width,希望MainWindow自动适合。Width="Auto"不起作用)

<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>

在SizeToContent =“Width”之后

enter image description here

1 个答案:

答案 0 :(得分:2)

这里的问题是你将宽度设置为auto,这意味着它将占用其父级的所有可用空间。

如果我查看可视树,则没有设置其他宽度,因此您的数据网格将覆盖整个应用程序。

应用程序B在调试中占用与应用程序A完全相同的空间的原因是因为Windows实际上认为它们是相同的应用程序,因为它们都是使用vshost启动的。

现在,您可以在父级上设置宽度,我更喜欢这样的东西:

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

您的数据网格仍将覆盖整个应用程序,如果您想在左侧或右侧创建空间以放置一些额外的控件,请移除width = auto setter。

现在,要么将静态宽度应用于数据网格,要么使用包装数据网格的网格,并使用动态宽度划分列。例如:

<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>

如果你还有一点空白,你想摆脱使用

<DataGrid ColumnWidth="*" ...

这将分隔列中的剩余空间。

修改

你真的不需要sreensizeconverter,你可以设置一个静态数字,为了你的方便,设置父窗口minwidth是一个快速而又脏的实现:

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();
    }
}

在App.xaml中(Window.Resources应该可以工作,但我认为你忘记了ResourceDictionary,这就是为什么它不能编译,我更喜欢App.xaml,因为现在你只需要导入一次就可以使用所有窗口和用户控件):

<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>

不过,你可以设置minwidth =&#34; 500&#34;和宽度=&#34; 950&#34;而你会达到同样的目的,我忘了清理那部分。