You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WPF矩形尺寸随列表中最大Item的Size动态变化

实现WPF中DataGrid修改Item值后自动更新最大尺寸到矩形

1. 让数据实体类实现INotifyPropertyChanged

你的Item类必须实现这个接口,这样当Size属性被修改时,能主动通知ViewModel值发生了变化:

public class SizeItem : INotifyPropertyChanged
{
    private double _size;
    public double Size
    {
        get => _size;
        set
        {
            if (_size != value)
            {
                _size = value;
                OnPropertyChanged(nameof(Size));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. ViewModel使用ObservableCollection并实现INotifyPropertyChanged

用ObservableCollection存储Item集合,它会在集合元素增删时触发变更通知;ViewModel自身实现接口,用来通知UI最大尺寸的变化:

public class MainViewModel : INotifyPropertyChanged
{
    private ObservableCollection<SizeItem> _items;
    public ObservableCollection<SizeItem> Items
    {
        get => _items;
        set
        {
            if (_items != value)
            {
                // 移除旧集合的事件监听,避免内存泄漏
                if (_items != null)
                {
                    foreach (var item in _items)
                    {
                        item.PropertyChanged -= Item_PropertyChanged;
                    }
                    _items.CollectionChanged -= Items_CollectionChanged;
                }
                _items = value;
                // 给新集合添加监听
                if (_items != null)
                {
                    foreach (var item in _items)
                    {
                        item.PropertyChanged += Item_PropertyChanged;
                    }
                    _items.CollectionChanged += Items_CollectionChanged;
                }
                RecalculateMaxSize();
                OnPropertyChanged(nameof(Items));
            }
        }
    }

    private double _maxSize;
    public double MaxSize
    {
        get => _maxSize;
        set
        {
            if (_maxSize != value)
            {
                _maxSize = value;
                OnPropertyChanged(nameof(MaxSize));
            }
        }
    }

    public MainViewModel()
    {
        // 初始化示例数据
        Items = new ObservableCollection<SizeItem>
        {
            new SizeItem { Size = 100 },
            new SizeItem { Size = 150 },
            new SizeItem { Size = 200 }
        };
    }

    // 监听单个Item的Size属性变化
    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(SizeItem.Size))
        {
            RecalculateMaxSize();
        }
    }

    // 监听集合的增删变化
    private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // 给新增Item绑定监听
        if (e.NewItems != null)
        {
            foreach (SizeItem item in e.NewItems)
            {
                item.PropertyChanged += Item_PropertyChanged;
            }
        }
        // 给移除Item解绑监听
        if (e.OldItems != null)
        {
            foreach (SizeItem item in e.OldItems)
            {
                item.PropertyChanged -= Item_PropertyChanged;
            }
        }
        RecalculateMaxSize();
    }

    // 重新计算最大Size值
    private void RecalculateMaxSize()
    {
        if (Items == null || Items.Count == 0)
        {
            MaxSize = 0;
            return;
        }
        MaxSize = Items.Max(item => item.Size);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3. XAML绑定配置

确保DataGrid的Size列是双向绑定,并且输入时立即更新数据源;矩形的宽高绑定到ViewModel的MaxSize:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <!-- 左侧DataGrid -->
        <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" Grid.Column="0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Size" Binding="{Binding Size, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </DataGrid.Columns>
        </DataGrid>
        <!-- 右侧红色矩形 -->
        <Grid Grid.Column="1">
            <Rectangle Fill="Red" Width="{Binding MaxSize}" Height="{Binding MaxSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
    </Grid>
</Window>

关键细节说明

  • UpdateSourceTrigger=PropertyChanged:让DataGrid文本框在输入时立即更新数据源,实现矩形尺寸实时同步
  • 集合替换时的事件解绑:必须移除旧Item的监听,否则会导致内存泄漏
  • 空集合判断:RecalculateMaxSize中处理空集合场景,避免空引用异常

内容的提问来源于stack exchange,提问作者mmdn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 15:42:25