繁体   English   中英

我如何将视图(具有自己的视图模型的数据上下文)与另一个视图模型的属性绑定

[英]How can i bind a view(having datacontext of own viewmodel) with another viewmodel's property

有两个视图和两个相应的视图模型。 现在我在 dasboardviewmodel 中有一个状态属性。 我必须在主视图中绑定该属性。 视图和视图模型在数据模板中链接。 我试图在家里调用仪表板 ViewModel 数据上下文,但它不起作用。 请任何人都可以帮助我或提供一个简单的例子,谢谢。

<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="cnamespace: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>

仪表板视图...

<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;

        //public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        //    => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

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

您可以定义一个 singleton class 作为端口, DashboardViewModel将在状态属性更新时更新它。

public class DashboardPort : INotifyPropertyChanged
{
    private DashboardPort()
    {
    }

    public static DashboardPort Instance = new DashboardPort();

    private bool _status;

    public bool Status
    {
        set
        {
            _status = value;
            OnPropertyChanged(nameof(Status));
        }
        get => _status;
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

两个视图模型中,您将定义端口的一个实例。

public DashboardPort DashboardPort => DashboardPort.Instance;

DashboardViewModel中,您将在状态属性更新时更新端口

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

最后, Dashboard.xaml中的 CheckBox 将从 Port 实例中读取其 state。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM