2014-10-23 3 views
0

Я хочу иметь возможность обмениваться элементами управления между моим главным окном и элементами управления вкладками. Прямо сейчас, у меня есть панель управления вкладкой и строка состояния в главном окне. Строка состояния содержит кнопку и индикатор выполнения. Я хочу поделиться индикатором прогресса. Когда кнопка нажата, она сбрасывает индикатор выполнения.TabControl - Share Main ViewModel

Вкладки содержат кнопку. При нажатии на нее должен увеличиваться индикатор выполнения на 1.

Что я сделал: после того, как я прорывался через SO/другой весь день, я смог установить это.

  • MainWindowView
  • -> Объявляет экземпляр MainWindowViewModel в XAML
  • -> Объявляет вкладки в UserControls в XAML б/с всегда будет иметь те же вкладки
  • TabControl1View
  • -> Объявляет экземпляр TabControl2ViewModel в xaml

Мне нужен совет о том, как разговаривать с MainWindowViewModel в TabControl1View.

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

х

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

Я нашел хороший ответ на использование шаблона посредника здесь: How can I update a property of mainWindowViewModel from another ViewModel?

Но я не понимаю, как я могу хранить ссылку на TabControl1ViewModel в MainWindowViewModel.

Также найдено множество статей, говорящих, чтобы объявить ViewModels внутри MainViewModel и отслеживать их, но они всегда были фрагментами кода.

Вопрос: как передать MainViewModel.Progress в TabControlViewModel?

Я сейчас идет вниз по пути пытается поставить что-то подобное в моей MainViewModel

MainViewModel.ProgressChanged = TabControlView. (Получить TabControlViewModel) .ProgressChanged

ответ

1

Когда вы сделаете это

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

или

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

Вы разрешаете представлению создать экземпляр MainWindowViewModel или TabControl1ViewModel самостоятельно и привязать его к datacontext вашего View. Это избавляет вас от контроля передачи любого параметра конструктора в элемент управления.

В конструкторе ваших MainWindowViewModel «S инициализации DataContext пользовательского элемента управления, как

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

View.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> 
+0

Спасибо! Застрял на этом весь день. – user1002479

+0

В любое время :) Приветствия – CarbineCoder