UWP:Grid.IsSharedSizeScope 和 SharedSizeGroup 的替代方案

问题描述 投票:0回答:3

我遇到了与以下旧论坛帖子中所述相同的问题:MSDN 上的问题
然而,出于某种原因,微软决定删除其中描述的答案中的功能。

我正在寻找的是一个具有 2+ 列的 ListView,第一列包含随机数据(因此是随机宽度元素),使第一列的宽度与内部最宽的元素相同。

c# wpf uwp
3个回答
1
投票

SharedSizeGroup
WPF独有的,在UWP中不存在。

目标:创建 SharedSizeGroup 的替代方案

为了了解测量值,我们需要查看所有控件并找到最大值。

我们将做什么

我们使用 FodyPropertyChanged.Fody nuget 包。虽然只读示例不需要它们,但如果您开始修改数据,它们会很有用。我添加

SizeChanged
事件处理程序并直接修改宽度。您可以设置一个属性并绑定到或创建一个行为,但这就是它的完成方式。

查看

<Page
    x:Class="TestUwp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:TestUwp"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DataContext="{d:DesignInstance Type=local:DataItem}"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">

    <ListView ItemsSource="{Binding TestData}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Grid ColumnSpacing="6" RowSpacing="6">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock
                            Grid.Column="0"
                            SizeChanged="LabelSizeChanged"
                            Text="{Binding FirstName}" />
                        <TextBlock Grid.Column="1" Text="{Binding LastName}" />
                    </Grid>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Page>

模型和视图模型

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace TestUwp
{
    public class DataItem : INotifyPropertyChanged
    {
        public DataItem(int id, string firstName, string lastName)
        {
            Id = id;
            FirstName = firstName;
            LastName = lastName;
        }

        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            TestData = new ObservableCollection<DataItem> {
                new DataItem(1, "Pauly", "Thurlborn"),
                new DataItem(2, "Orbadiah", "Ewen"),
                new DataItem(3, "Britni"  ,"Smead"),
                new DataItem(4, "Fionna"  ,"Jennemann"),
                new DataItem(5, "Ashley" ,"Stoddart"),
                new DataItem(6, "Bradford", "Kaesmakers"),
                new DataItem(7, "Maxy" ,"Lemon"),
                new DataItem(8, "Rasia" ,"Comber"),
                new DataItem(9, "Colas" ,"Shepton"),
                new DataItem(10, "Cacilie" ,"Tummons"),
            };
            DataContext = this;
        }
        public ObservableCollection<DataItem> TestData { get; set; }
        private List<ColumnDefinition> _columns = new List<ColumnDefinition>();
        private double _colSize = 0.0;
        private void LabelSizeChanged(object sender, SizeChangedEventArgs e)
        {
            var item = (dynamic)sender;
            var grid = (Grid)item.Parent;
            var column = grid.ColumnDefinitions[0];
            if (!_columns.Contains(column))
            {
                _columns.Add(column);
            }
            var adjustments = new List<ColumnDefinition>();
            if (item.ActualWidth > _colSize)
            {
                _colSize = item.ActualWidth;
                adjustments.AddRange(_columns);
            }
            else
            {
                adjustments.Add(column);
            }
            foreach (var col in adjustments)
            {
                col.Width = new GridLength(_colSize);
            }
        }
    }
}

这个想法的来源源自Xamarin。


0
投票

我为winui做了模仿,参见repo

这里是如何使用,就像在WPF中一样

<ListView ItemsSource="{x:Bind DataCollection}" h:ColumnSharedSizeHelper.IsSharedSizeScope="True"
          Width="400" VerticalAlignment="Center">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid ColumnDefinitions="Auto,*">
                <TextBlock Text="{Binding Name}" VerticalAlignment="Center" h:ColumnSharedSizeHelper.SharedSizeGroup="SampleGroup"/>
                <TextBox Grid.Column="1" Text="{Binding Salary}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

-3
投票

我认为这个stackoverflow问题中给出的解决方案应该可以满足您的要求,您只需将第一列更改为

Auto
而不是
*

来自帖子:


<Page.Resources>

    <DataTemplate x:Key="DataTemplate1"  >
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Gray">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <TextBlock Text="{Binding Name1}"/>
            </StackPanel>
            <StackPanel Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <TextBlock Text="{Binding Name2}"/>

            </StackPanel>
            <StackPanel Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <TextBlock Text="{Binding Name3}"/>

            </StackPanel>
        </Grid>
    </DataTemplate>
</Page.Resources>

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

    <ListView Name="MyList" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"  VerticalContentAlignment="Stretch" VerticalAlignment="Stretch" Background="Yellow" ItemTemplate="{StaticResource DataTemplate1}">

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemsPanel>

            <ItemsPanelTemplate
                <!-- Here is the panel that will contain the items -->
                <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Background="Pink" VerticalAlignment="Stretch"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
</Grid>

以及背后的代码。只是尝试一下,没有使用 MVVM

这是cs

        List<test> li = new List<test>();
    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            li.Add(new test()
            {
                Name1 = "Anobik1" + i.ToString(),
                Name2 = "Anobik1"                    +i.ToString(),
                Name3 = "Anobik1"                    +i.ToString()
            });
        }
        MyList.ItemsSource = li;

    }

我绑定的类如下

 class test
{
    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Name3 { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.