2014-12-03 50 views
4

我有一個具有選項卡控件的主視圖。當選中一個標籤時,它會調用相應的視圖來顯示。我在視圖模型中有一個函數,它必須知道選擇哪個選項卡來執行操作。我如何實現這一目標?視圖模型如何知道選擇了哪個選項卡?獲取視圖模型中的選定選項卡(wpf)

+0

我想你可以將選項卡控件的選定屬性綁定到viewmodel中的一個屬性並在那裏訪問它。它會知道選擇什麼,因爲...這就是模型綁定:) – Sinaesthetic 2014-12-03 03:58:09

+0

謝謝。將嘗試。 – nan 2014-12-03 04:02:20

+0

我在下面包含一個例子。 – Sinaesthetic 2014-12-03 04:23:52

回答

6

很簡單:

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication2" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <local:TestViewModel x:Key="MainViewModel"/> 
    </Window.Resources> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="50"/> 
     </Grid.RowDefinitions> 
     <TabControl DataContext="{StaticResource MainViewModel}" 
        SelectedIndex="{Binding Selected}" 
        Grid.Row="0" 
        x:Name="TestTabs"> 
      <TabItem Header="Section 1"/> 
      <TabItem Header="Section 2"/> 
      <TabItem Header="Section 3"/> 
     </TabControl> 
     <Button Content="Check 
       Selected Index" 
       Grid.Row="1" 
       x:Name="TestButton" 
       Click="TestButton_OnClick"/> 
    </Grid> 
</Window> 

該模型在這裏被定義,聲明,作爲數據上下文。 selectedIndex屬性綁定到模型,以便任何它的變化時,它被映射到視圖模型的屬性格式也將改變

class TestViewModel : INotifyPropertyChanged 
{ 
    private int _selected; 
    public int Selected 
    { 
     get { return _selected; } 
     set 
     { 
      _selected = value; 
      OnPropertyChanged("Selected"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
} 

這實現INotifyPropertyChanged所以視圖將與它註冊。在這裏的處理程序中,我輸出Selected的值以顯示您在更改它們時的值。

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void TestButton_OnClick(object sender, RoutedEventArgs e) 
    { 
     var vm = TestTabs.DataContext as TestViewModel; 
     MessageBox.Show(string.Format("You selected tab {0}", vm.Selected)); 
    } 
} 

這將獲取視圖模型,然後向我們顯示屬性實際上已更新。

+0

我的要求稍有不同,但這種解決方案正是醫生訂購的,完全相同。好一個! – AndyUK 2017-05-10 16:06:41

0

您可以使用Selector基類提供的SelectionChanged事件。 SelectionChangedEventArgs將包含新選擇(和取消選擇)的項目。或者,您可以將Selector Base類的SelectedItem綁定到ViewModel中的屬性,然後在setter中執行一些邏輯。一般而言,MVVM將視圖特定的對象傳遞給ViewModels被認爲是違反了它 - 它將UI框架(本例中爲WPF)緊密地耦合到更通用的ViewModel邏輯。更好的方法是將事件處理程序放入UI代碼中,然後依次作用於視圖模型,但不將View對象作爲參數傳遞。

+0

這是正確的 - 收集您在該處理程序中所需的信息,然後將其傳遞給DataContext(VM)上的方法 – Andrew 2014-12-03 04:07:17

+0

謝謝。我幾天前從mvvm開始,現在仍在掙扎。 – nan 2014-12-03 04:10:00

+0

歡迎您! MVVM絕對需要一些習慣 - 數據所屬的細節哪裏不重要。 – Andrew 2014-12-03 04:11:38

0

這是一個簡單的例子。

你應該是標籤的的ItemsSource綁定到您的ObservableCollection,並應與有關應創建選項卡的信息持有的機型。

這裏是虛擬機和代表標籤頁型號:

public class ViewModel 
{ 
    public ObservableCollection<TabItem> Tabs { get; set; } 
    public ViewModel() 
    { 
     Tabs = new ObservableCollection<TabItem>(); 
     Tabs.Add(new TabItem { Header = "One", Content = "One's content" }); 
     Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" }); 
    } 
} 
public class TabItem 
{ 
    public string Header { get; set; } 
    public string Content { get; set; } 
} 

Here`s查看和VM結合

<Window x:Class="WpfApplication12.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.DataContext> 
    <ViewModel 
     xmlns="clr-namespace:WpfApplication12" /> 
</Window.DataContext> 
<TabControl 
ItemsSource="{Binding Tabs}"> 
<TabControl.ItemTemplate> 
    <!-- this is the header template--> 
    <DataTemplate> 
     <TextBlock 
      Text="{Binding Header}" /> 
    </DataTemplate> 
</TabControl.ItemTemplate> 
<TabControl.ContentTemplate> 
    <!-- this is the body of the TabItem template--> 
    <DataTemplate> 
     <----- usercontrol namespace goes here---> 
    </DataTemplate> 
</TabControl.ContentTemplate> 

來源:link

0

在視圖中,您將SelectedIndex設置爲正確TY上的TabControl:

xmlns:cal="http://www.caliburnproject.org" 

<TabControl cal:Message.Attach="[SelectionChanged] = [OnTabSelectionChanged()]" 
        SelectedIndex="{Binding SelectedIndexTab}"> 
      <TabItem Header="Tab 1"/> 
      <TabItem Header="Tab 2"/> 
</TabControl> 

在視圖模型,你聲明的公共屬性名稱SelectedIndexTabOnTabSelectionChanged()方法操作。

public int SelectedIndexTab { get; set; } 

在這個例子中,我使用Caliburn來捕獲TabControl的SelectionChange事件。

+0

嗨@apo,我使用這個解決方案,但我不知道爲什麼,在選擇最後一個標籤事件OnTabSelectionChanged()被調用無限。 – 2017-12-05 09:50:42

相關問題