【问题标题】:Fixed Proportional Sizing in WPF固定 WPF 中的比例大小
【发布时间】:2016-06-16 18:42:06
【问题描述】:

我有一个 wpf 网格,其中两列应该等距。我知道星号 (*) 大小,但是当我将列宽设置为等间距时,实际列在运行时会发生变化。网格的整体宽度将根据窗口大小而变化,但我想强制两列在该网格内始终具有相等的宽度。

我目前有很多嵌套元素分配给第一列,而第二列只有一个 ItemsControl 面板,它只在执行按钮事件操作时显示项目......所以有时它是空的。我的假设是,因为第二列是空的,所以第一列会自动占用尽可能多的空间。有没有办法强制列保持按比例固定?这是我的基本设置:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"></ColumnDefinition>
        <ColumnDefinition Width="1*" ></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="0">
        <!-- Lots of nested WPF elements inside this stack panel -->
    </StackPanel>
    <ItemsControl Grid.Column="1" ItemsSource="{Binding Tasks}">
        <ItemsControl.Template>
            <ControlTemplate TargetType="{x:Type ItemsControl}" >
                <ItemsPresenter/>
            </ControlTemplate>
        </ItemsControl.Template>

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="cc:Tasks">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Title}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

我读过this thread,但我不完全确定这个答案是否适合这个问题。

【问题讨论】:

  • UniformGrid 会比常规网格更适合您想要做的事情吗?
  • 你是说当Tasks为null或者为空的时候,第二列会改变宽度吗?当第一列“尽可能多地占用空间”时,它占用了多少空间?整个窗户? +1 UniformGrid 顺便说一句。在上面设置 Rows="1" 和 Columns="2"。
  • 第一列根据需要占用尽可能多的空间。我有一个显示文件路径的文本框。因此,当用户更改文件路径时,整列的宽度会更改以进行调整。我宁愿将文本框宽度绑定到第一列宽度,然后将其绑定为整个网格宽度的 50%。感谢您对 UniformGrid 的建议。我会调查的。
  • 你在左列最外层的元素上有 Horizo​​ntalAlignment="Stretch" 吗?听起来左列内容是自动调整大小而不是调整其容器的大小,这可能仍然是 UniformGrid 的问题。有时,这些东西在 WPF 中可能会令人沮丧。
  • 但是如果 WPF 没有足够的空间,你已经把它放在一个真正的凝灰岩中。我会把每一列放在滚动视图中。并查看使用转换器将每个宽度与 Grid 实际宽度绑定到一半。

标签: c# wpf


【解决方案1】:

按照@Paparazzi 的建议,我创建了一个转换器来绑定滚动查看器的宽度。我是这样做的:

在后面的 C# 代码中,我创建了转换器:

public class PercentageConverter : MarkupExtension, IValueConverter
{
    private static PercentageConverter _instance;

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter);
    }

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

    #endregion

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return _instance ?? (_instance = new PercentageConverter());
    }
}

然后,在我的 .xaml 代码中,我像这样使用它:

<UserControl.Resources>
    <ResourceDictionary>
        <local:PercentageConverter x:Key="PercentageConverter"></local:PercentageConverter>
    </ResourceDictionary>
</UserControl.Resources>

<Grid Name="ParentGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        <ColumnDefinition Width="Auto" ></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ScrollViewer Grid.Column="0" 
            HorizontalScrollBarVisibility="Auto" 
            MinWidth="200" 
            Width="{Binding Path=ActualWidth, ElementName=ParentGrid, Converter={StaticResource PercentageConverter}, ConverterParameter='0.6'}">
        <StackPanel Orientation="Vertical" ScrollViewer.CanContentScroll="True">
            <!-- Lots of other WPF Framework elements -->
        </StackPanel>
    </ScrollViewer>
    <ItemsControl Grid.Column="1" ItemsSource="{Binding Tasks}">
        <ItemsControl.Template>
            <ControlTemplate TargetType="{x:Type ItemsControl}" >
                <ItemsPresenter/>
            </ControlTemplate>
        </ItemsControl.Template>

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="cc:Tasks">
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Title}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

关键是在ResourceDictionary中定义转换器。然后,我将 ScrollViewer 元素的 width 属性设置为绑定到父网格的实际宽度,使用转换器将其设置为一定的百分比(在这种情况下,0.6 是参数或父网格整体宽度的 60%网格)。我希望这对将来的某人有所帮助。

【讨论】:

    猜你喜欢
    • 2019-12-30
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2015-05-06
    • 2013-03-03
    • 1970-01-01
    相关资源
    最近更新 更多