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

绑定SizeChanged事件到ViewModel时如何接收控件宽高参数

问题解决方法

你可以通过两种无侵入的方式拿到SizeChanged事件触发时的控件实际宽高,不破坏MVVM分层规则。

方法1:直接传递事件参数(改动量最小)

首先修正你原有XAML里未闭合的标签,同时给InvokeCommandAction开启事件参数传递配置:

<Grid>
    <Interactivity:Interaction.Behaviors>
        <Interactions:EventTriggerBehavior EventName="SizeChanged">
            <Interactions:InvokeCommandAction 
                Command="{Binding OnSizeChanged}"
                PassEventArgsToCommand="True"/>
        </Interactions:EventTriggerBehavior> <!-- 你原来的代码这里缺少闭合的>符号 -->
    </Interactivity:Interaction.Behaviors>
</Grid>

调整ViewModel里的命令定义,支持接收事件参数:

// 用泛型版RelayCommand接收SizeChangedEventArgs类型参数
public IRelayCommand<SizeChangedEventArgs> OnSizeChanged => new RelayCommand<SizeChangedEventArgs>(SizeChangedEvent);

private void SizeChangedEvent(SizeChangedEventArgs e)
{
    // 从参数中直接获取控件最新的宽高
    double currentWidth = e.NewSize.Width;
    double currentHeight = e.NewSize.Height;

    // 后续业务逻辑
}

如果你使用CommunityToolkit.Mvvm的源码生成器,可以简化命令写法,不需要手动声明IRelayCommand字段:

[RelayCommand]
private void OnSizeChanged(SizeChangedEventArgs e)
{
    double currentWidth = e.NewSize.Width;
    double currentHeight = e.NewSize.Height;
}

注意:WPF、UWP、WinUI 3框架下的SizeChanged事件参数类型都是SizeChangedEventArgs,NewSize属性返回的就是控件渲染完成后的实际尺寸,和你在控件后台代码里拿到的值完全一致。

方法2:绑定实际尺寸属性(ViewModel完全不依赖UI框架)

如果你不想让ViewModel层引用UI相关的类型(比如做跨平台复用、单元测试不依赖UI环境),可以放弃事件命令,直接用OneWayToSource模式把控件的实际宽高绑定到ViewModel属性:

<Grid
    ActualWidth="{Binding GridActualWidth, Mode=OneWayToSource}"
    ActualHeight="{Binding GridActualHeight, Mode=OneWayToSource}">
    <!-- 控件内部内容 -->
</Grid>

ViewModel中对应属性:

private double _gridActualWidth;
public double GridActualWidth
{
    get => _gridActualWidth;
    set
    {
        _gridActualWidth = value;
        HandleSizeChange();
    }
}

private double _gridActualHeight;
public double GridActualHeight
{
    get => _gridActualHeight;
    set
    {
        _gridActualHeight = value;
        HandleSizeChange();
    }
}

private void HandleSizeChange()
{
    // 这里直接使用_GridActualWidth和_GridActualHeight即可,和SizeChanged事件触发时机、返回值完全一致
}

注意:不要绑定Width/Height属性,这两个是开发者设置的期望布局尺寸,默认值是NaN,拿不到实际渲染大小;必须绑定ActualWidth/ActualHeight,这两个属性是控件布局完成后由框架更新的真实尺寸,只读,所以用OneWayToSource模式从UI推送到ViewModel即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 21:57:22