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

WPF中如何将绑定自有ViewModel的View与另一个ViewModel属性绑定?

问题需求

现有两个View(HomeView、DashboardView)和对应的ViewModel(HomeViewModel、DashboardViewModel),DashboardViewModel包含status属性,需要在HomeView中绑定该属性。尝试通过DataTemplate关联View与ViewModel,并在HomeView中调用DashboardViewModel的DataContext,但绑定未生效,寻求解决方法或示例。


现有代码

HomeView.xaml

<UserControl x:Class="Demo.View.Home"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Demo.View" 
             xmlns:viewmodel="clr-namespace:Demo.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="BlueViolet">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <CheckBox Content="second" IsChecked="{Binding status}" Margin="200,100,0,0"/>
    </Grid>
</UserControl>

DashboardView.xaml

<UserControl x:Class="Demo.View.Dashboard"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Demo.View"
             xmlns:vm="clr-namespace:Demo.ViewModel"
             xmlns:dt="clr-namespace:DefectTracking;assembly=DefectTrackingControl"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="Red">
        <StackPanel>
            <CheckBox Content="one" IsChecked="{Binding status}" Margin="200,100,10,10"/>
        </StackPanel>
    </Grid> 
</UserControl>

HomeViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace Demo.ViewModel
{
    public class HomeViewModel : INotifyPropertyChanged
    {
        private bool _check;

        public bool Check
        {
            get { return _check; }
            set { _check = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

DashboardViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;
using DefectTracking;
using System.Runtime.CompilerServices;
using System.Windows;

namespace Demo.ViewModel
{
    public class DashboardViewModel : DependencyObject, INotifyPropertyChanged
    {
        public DispatcherTimer DispatchTimer = new DispatcherTimer();

        public DashboardViewModel()
        {
            DispatchTimer.Interval = TimeSpan.FromMilliseconds(1000);
            DispatchTimer.Tick += dispatchTimer_Tick;
            DispatchTimer.Start();
        }

        private bool _status;
        public bool status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;
                OnPropertyChanged(nameof(status));
            }
        }

        private void dispatchTimer_Tick(object sender, EventArgs e)
        {
            status = !status;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

解决方法

步骤1:修改HomeViewModel,添加DashboardViewModel实例

HomeView的DataContext是HomeViewModel,要访问DashboardViewModel的status,需让HomeViewModel持有其实例:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Threading;

namespace Demo.ViewModel
{
    public class HomeViewModel : INotifyPropertyChanged
    {
        private bool _check;

        // 初始化DashboardViewModel实例
        public DashboardViewModel DashboardVM { get; set; } = new DashboardViewModel();

        public bool Check
        {
            get { return _check; }
            set 
            { 
                _check = value;
                OnPropertyChanged(nameof(Check));
            }
        }

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

步骤2:修正HomeView的绑定路径

绑定需指向HomeViewModel中的DashboardVM.status,而非直接status:

<CheckBox Content="second" IsChecked="{Binding DashboardVM.status}" Margin="200,100,0,0"/>

步骤3:确保View的DataContext正确设置

在HomeView构造函数中设置DataContext:

using System.Windows.Controls;

namespace Demo.View
{
    public partial class Home : UserControl
    {
        public Home()
        {
            InitializeComponent();
            DataContext = new ViewModel.HomeViewModel();
        }
    }
}

DashboardView同理(若需独立使用):

using System.Windows.Controls;

namespace Demo.View
{
    public partial class Dashboard : UserControl
    {
        public Dashboard()
        {
            InitializeComponent();
            DataContext = new ViewModel.DashboardViewModel();
        }
    }
}

可选:全局DataTemplate关联View与ViewModel

若希望自动根据ViewModel加载对应View,可在App.xaml中定义DataTemplate:

<Application x:Class="Demo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:Demo.ViewModel"
             xmlns:view="clr-namespace:Demo.View"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <DataTemplate DataType="{x:Type vm:DashboardViewModel}">
            <view:Dashboard/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:HomeViewModel}">
            <view:Home/>
        </DataTemplate>
    </Application.Resources>
</Application>

后续在容器(如ContentControl)中绑定ViewModel时,会自动加载对应View。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:15:43