固定WPF中的比例大小

时间:2016-06-16 18:42:06

标签: c# wpf

我有一个带有两列的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,但我不完全确定这个答案是否适合这个问题。

1 个答案:

答案 0 :(得分:0)

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

在后面的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%)格)。我希望这有助于将来的某个人。