TabControl-共享主视图模型

本文关键字:模型 主视图 共享 TabControl- | 更新日期: 2023-09-27 18:27:36

我希望能够在主窗口和选项卡控件之间共享控件。现在,我在主窗口上有一个选项卡控件和状态栏。状态栏包含一个按钮和进度栏。我想分享进度条。单击该按钮时,它会重置进度条。

选项卡包含一个按钮。单击时,进度条应增加1。

我所做的:经过一整天的SO/other挖掘,我能够设置这个。

  • 主窗口视图
  • ->在xaml中声明MainWindowViewModel的实例
  • ->将选项卡声明为xaml b/c中的用户控件将始终具有相同的选项卡
  • 选项卡控件1视图
  • ->在xaml中声明TabControl2ViewModel的实例

我需要关于如何在TabControl1View中与MainWindowViewModel对话的建议。

<Window x:Class="TabControlTest.MainWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TabControlTest"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<DockPanel>
    <StatusBar DockPanel.Dock="Bottom">
        <StatusBarItem HorizontalContentAlignment="Stretch" DockPanel.Dock="Top">
            <Button Height="25" Content="Reset" Command="{Binding MainWindowViewModel_ButtonClickCommand}"/>
        </StatusBarItem>
        <StatusBarItem HorizontalContentAlignment="Stretch" DockPanel.Dock="Bottom">
            <ProgressBar Height="25" Maximum="10" Value="{Binding MainWindowViewModel_Progress, Mode=TwoWay}"/>
        </StatusBarItem>
    </StatusBar>
    <TabControl>
        <TabItem>
            <local:TabControl1View/>
        </TabItem>
    </TabControl>
</DockPanel>

class MainWindowViewModel : ViewModelBase
{
    int progress = 0;
    public int MainWindowViewModel_Progress
    {
        get
        {
            return progress;
        }
        set
        {
            SetAndNotify(ref this.progress, value, () => this.MainWindowViewModel_Progress);
        }
    }
    ICommand _ButtonClickCommand;
    public ICommand MainWindowViewModel_ButtonClickCommand
    {
        get
        {
            return _ButtonClickCommand ?? (_ButtonClickCommand = new CommandHandler(() => MainWindowViewModel_ButtonClick(), true));
        }
    }
    public void MainWindowViewModel_ButtonClick()
    {
        MainWindowViewModel_Progress = 0; // Reset progress
    }
}

x

<UserControl x:Class="TabControlTest.TabControl1View"
         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:TabControlTest"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
    <local:TabControl1ViewModel/>
</UserControl.DataContext>
<Grid>
    <Button Content="UP" Command="{Binding TabControl1ViewModel_UpClickCommand}"/>
</Grid>

class TabControl1ViewModel : ViewModelBase
{
    ICommand _UpClickCommand;
    public ICommand TabControl1ViewModel_UpClickCommand
    {
        get
        {
            return _UpClickCommand ?? (_UpClickCommand = new CommandHandler(() => TabControl1ViewModel_UpClick(), true));
        }
    }
    public void TabControl1ViewModel_UpClick()
    {
        // I want to increase the progress bar here
    }
}

我在这里找到了一个关于使用中介模式的好答案:如何从另一个ViewModel更新mainWindowViewModel的属性?

但我不明白如何在MainWindowViewModel中存储对TabControl1ViewModel的引用。

还发现了大量的文章,说要在MainViewModel中声明ViewModel并跟踪它们,但它们总是代码片段。

问题:如何传递MainViewModel.进度到TabControlViewModel

我现在正试图在我的MainViewModel 中放入这样的东西

MainViewModel.ProgressChanged=选项卡控制视图。(获取TabControlViewModel).ProgressChanged

TabControl-共享主视图模型

当您执行此时

<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>

<UserControl.DataContext>
    <local:TabControl1ViewModel/>
</UserControl.DataContext>

您让视图自己创建MainWindowViewModelTabControl1ViewModel的实例,并将其绑定到视图的数据上下文。这会使您失去将任何构造函数参数传递给控件的控制。

MainWindowViewModel的构造函数中,初始化用户控件的数据内容,如

class MainWindowViewModel
{
    MainWindowViewModel
    {
     ChildViewModel  = new TabControl1ViewModel(this);
    }
    public TabControl1ViewModel ChildViewModel {get; private set;}
}
class TabControl1ViewModel
{
    public MainWindowViewModel ParentViewModel {get; private set;}
    TabControl1ViewModel(MainWindowViewModel mainWindowViewModel)
    {
        ParentViewModel  = mainWindowViewModel;
    }
}

查看Xaml

<Window x:Class="TabControlTest.MainWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TabControlTest"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:MainWindowViewModel/>
</Window.DataContext>
<DockPanel>
  .
  .
  .
   <TabControl>
        <TabItem>
            <local:TabControl1View DataContext={Binding ChildViewModel}/>
        </TabItem>
   </TabControl>
</DockPanel>