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

Prism.WPF:导航时修改MainWindow的Window.Effect实现模糊效果

基于Prism的WPF导航时模糊效果实现方案

一、修复导航前模糊不生效的问题

1. 纠正属性赋值方式

你之前直接给私有字段_fuzzy赋值不会触发UI的属性变更通知,必须通过公开属性的setter(Fuzzy = ef)设置,Prism的SetProperty才会触发PropertyChanged事件,让UI同步更新效果。修改后的模糊设置方法:

private void PerformBlur()
{
    Fuzzy = new BlurEffect { Radius = 4 };
}

2. 确保UI先更新再执行导航

_regionManager.RequestNavigate是异步操作,UI更新模糊效果需要优先占用UI线程处理。可以通过Dispatcher将导航操作延迟到UI队列的后续执行,确保模糊效果先渲染完成:

private async void Navigate(string viewName)
{
    PerformBlur();
    // 让UI线程优先处理模糊效果更新
    await Application.Current.Dispatcher.InvokeAsync(() => {});
    _regionManager.RequestNavigate("ContentRegion", viewName);
}

3. 符合MVVM规范的命令绑定

菜单按钮直接绑定ViewModel的DelegateCommand,无需后台代码:

<!-- 导航按钮示例 -->
<Button Content="跳转至目标页面" Command="{Binding NavigateCommand}" CommandParameter="TargetViewName" />

ViewModel中初始化命令:

public DelegateCommand<string> NavigateCommand { get; private set; }

public MainWindowViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
    NavigateCommand = new DelegateCommand<string>(Navigate);
}

二、模糊效果的动画实现

方式1:ViewModel驱动的属性动画(MVVM友好)

在ViewModel中新增控制模糊半径的属性,通过绑定关联到BlurEffect:

private double _blurRadius;
public double BlurRadius 
{ 
    get => _blurRadius; 
    set => SetProperty(ref _blurRadius, value); 
}

// 初始化时绑定BlurRadius到BlurEffect的Radius
public MainWindowViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
    NavigateCommand = new DelegateCommand<string>(Navigate);
    
    var blurEffect = new BlurEffect();
    BindingOperations.SetBinding(blurEffect, BlurEffect.RadiusProperty, 
        new Binding(nameof(BlurRadius)) { Source = this });
    Fuzzy = blurEffect;
}

触发动画的方法:

private void AnimateBlur()
{
    var animation = new DoubleAnimation
    {
        From = 0,
        To = 4,
        Duration = TimeSpan.FromMilliseconds(300),
        EasingFunction = new QuadraticEase() // 平滑缓动效果
    };
    BeginAnimation(nameof(BlurRadius), animation);
}

修改导航方法,启动动画并在导航完成后恢复:

private async void Navigate(string viewName)
{
    AnimateBlur();
    await Application.Current.Dispatcher.InvokeAsync(() => {});
    
    _regionManager.RequestNavigate("ContentRegion", viewName, result => 
    {
        // 导航完成后执行模糊消失动画
        var resetAnimation = new DoubleAnimation(0, TimeSpan.FromMilliseconds(300));
        BeginAnimation(nameof(BlurRadius), resetAnimation);
    });
}

方式2:纯XAML的Storyboard动画(解耦UI逻辑)

在MainWindow的资源中定义动画:

<Window.Resources>
    <QuadraticEase x:Key="QuadraticEase"/>
    <Storyboard x:Key="BlurInAnimation">
        <DoubleAnimation 
            Storyboard.TargetProperty="(Effect).(BlurEffect.Radius)"
            From="0" To="4" Duration="0:0:0.3"
            EasingFunction="{StaticResource QuadraticEase}"/>
    </Storyboard>
    <Storyboard x:Key="BlurOutAnimation">
        <DoubleAnimation 
            Storyboard.TargetProperty="(Effect).(BlurEffect.Radius)"
            To="0" Duration="0:0:0.3"
            EasingFunction="{StaticResource QuadraticEase}"/>
    </Storyboard>
</Window.Resources>

通过DataTrigger绑定ViewModel的导航状态标志:

<Window.Style>
    <Style TargetType="Window">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsNavigating}" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource BlurInAnimation}"/>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <BeginStoryboard Storyboard="{StaticResource BlurOutAnimation}"/>
                </DataTrigger.ExitActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Style>

ViewModel中新增导航状态属性:

private bool _isNavigating;
public bool IsNavigating 
{ 
    get => _isNavigating; 
    set => SetProperty(ref _isNavigating, value); 
}

修改导航方法控制状态:

private async void Navigate(string viewName)
{
    IsNavigating = true;
    await Application.Current.Dispatcher.InvokeAsync(() => {});
    
    _regionManager.RequestNavigate("ContentRegion", viewName, result => 
    {
        IsNavigating = false;
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:45:59