You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

WinUI 3中如何将任务栏文本绑定到父窗口的视图模型

WinUI 3中如何将任务栏文本绑定到父窗口的视图模型

嗨,我来帮你搞定这个绑定需求!你要把嵌入在WindowUserHomeView里的UserHomeTaskBar(也就是你的Taskbar用户控件)的日期时间文本,通过x:Bind绑定到父窗口的WindowUserHomeViewModel,其实有两种实用的实现方式,我一步步给你讲清楚:

方法一:直接通过RelativeSource绑定到父窗口的ViewModel

这种方法不需要修改用户控件的后台代码,直接在XAML里通过RelativeSource找到父窗口,再绑定到它的DataContext(也就是你的WindowUserHomeViewModel)里的属性。

步骤1:确保父窗口的ViewModel已正确设置

首先你的WindowUserHomeView得把DataContext设为WindowUserHomeViewModel,而且ViewModel里要有一个带通知的日期时间属性,比如:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Microsoft.UI.Xaml;

public class WindowUserHomeViewModel : INotifyPropertyChanged
{
    private DateTime _currentDateTime;
    public DateTime CurrentDateTime
    {
        get => _currentDateTime;
        set
        {
            if (_currentDateTime != value)
            {
                _currentDateTime = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // 加个定时器实时更新时间,让UI跟着动起来
    public WindowUserHomeViewModel()
    {
        CurrentDateTime = DateTime.Now;
        var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
        timer.Tick += (s, e) => CurrentDateTime = DateTime.Now;
        timer.Start();
    }
}

步骤2:修改Taskbar的XAML绑定

在你的taskbar.xaml里,找到显示日期时间的TextBlock,把x:Bind的路径指向父窗口的ViewModel属性:

<TextBlock 
    Text="{x:Bind Path=((Microsoft.UI.Xaml.Window)RelativeSource.FindAncestor, AncestorType=Microsoft.UI.Xaml.Window).DataContext.CurrentDateTime, Mode=OneWay, StringFormat='{}{0:yyyy-MM-dd HH:mm:ss}'}"
    VerticalAlignment="Center"
    HorizontalAlignment="Right"
    Margin="0 0 20 0"/>

这里要注意几个点:

  • RelativeSource.FindAncestor用来向上查找父窗口类型的元素,因为x:Bind是强类型绑定,必须明确指定AncestorType的完整类型
  • Mode=OneWay是因为我们只需要从ViewModel到UI的单向绑定,不需要反向更新
  • StringFormat可以根据你的需求调整日期时间的显示样式

方法二:通过依赖属性实现解耦绑定(更推荐复用场景)

如果你的Taskbar用户控件需要在多个页面复用,这种方法更合适——给Taskbar添加一个依赖属性,父窗口把ViewModel的日期时间绑定到这个属性,控件内部再绑定到自己的依赖属性,这样控件和父ViewModel完全解耦。

步骤1:给Taskbar添加依赖属性

Taskbar.xaml.cs里添加一个DateTime类型的依赖属性:

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

public sealed partial class Taskbar : UserControl
{
    // 定义依赖属性
    public static readonly DependencyProperty CurrentDateTimeProperty =
        DependencyProperty.Register(
            nameof(CurrentDateTime),
            typeof(DateTime),
            typeof(Taskbar),
            new PropertyMetadata(DateTime.Now));

    // 包装属性,方便代码访问
    public DateTime CurrentDateTime
    {
        get => (DateTime)GetValue(CurrentDateTimeProperty);
        set => SetValue(CurrentDateTimeProperty, value);
    }

    public Taskbar()
    {
        this.InitializeComponent();
    }
}

步骤2:修改Taskbar的XAML绑定

控件内部直接x:Bind到自己的依赖属性,写法更简洁:

<TextBlock 
    Text="{x:Bind CurrentDateTime, Mode=OneWay, StringFormat='{}{0:yyyy-MM-dd HH:mm:ss}'}"
    VerticalAlignment="Center"
    HorizontalAlignment="Right"
    Margin="0 0 20 0"/>

步骤3:父窗口绑定Taskbar的依赖属性

WindowUserHomeView.xaml里引用Taskbar的时候,把它的CurrentDateTime绑定到ViewModel的属性。假设你的父窗口已经把ViewModel作为页面属性暴露(比如public WindowUserHomeViewModel ViewModel { get; } = new WindowUserHomeViewModel();),可以这样写:

<controls:Taskbar 
    CurrentDateTime="{x:Bind ViewModel.CurrentDateTime, Mode=OneWay}"/>

如果父窗口的DataContext直接是WindowUserHomeViewModel,也可以这样绑定:

<controls:Taskbar 
    CurrentDateTime="{x:Bind DataContext.CurrentDateTime, Mode=OneWay}"/>

备注:内容来源于stack exchange,提问作者Ming

火山引擎 最新活动