wpf UWP:Grid的替代方案,IsSharedSizeScope和SharedSizeGroup

axr492tv  于 2023-11-21  发布在  其他
关注(0)|答案(3)|浏览(217)

我得到了相同的问题,如以下所述,旧的,论坛帖子:Issue on MSDN
然而,出于某种原因,微软决定删除答案中描述的功能。
我正在寻找的是一个ListView与2+列,第一列包含随机数据(因此随机宽度元素),使第一列的宽度与最宽的元素内相同。

fykwrbwg

fykwrbwg1#

SharedSizeGroupWPF专用的,在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>

字符串

Model和ViewModel

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


这个idea的源代码来自Xamarin。

mqkwyuun

mqkwyuun2#

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

字符串

7gyucuyw

7gyucuyw3#

我认为this stackoverflow question中给出的解决方案应该可以满足您的要求,您只需将第一列更改为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; }
}

相关问题