2013-03-04 84 views
3

這就是問題所在。我有一個窗口分成三個面板。中間包含一個繪圖表面,左側包含一個選項卡控件。選項卡控件的選項卡每個都包含一個必須在右側面板中打開新菜單的按鈕列表。我無法弄清楚如何在代碼中這樣做,所以我在C#中運行時分別創建了每個按鈕。似乎有必要有一個更好的方法去實現它。我目前調用下面的按鈕點擊事件函數來在運行時的右側面板中的TabControl中繪製不同的菜單。它需要一個字符串參數來指定要繪製的菜單集,儘管此時我只寫了一個菜單的代碼。以下是函數和xml的代碼。有沒有更好的方法來解決這個問題?運行時更新TabControl內容

XML:

<TabControl DockPanel.Dock="Right" Background="White" x:Name="tabctrl"> 
     <TabItem Height ="38" Name="Tab1" Header="tab3"/> 
    </TabControl> 

C#:

private void menuOpen(string menuSelected) 
    { 

     //Logic statement for what menu is being opened 
     switch (menuSelected) 
     { 
      case "BackGround": 
       { 
        //Remove Current Tabs 


        //Initialize Tab Item, set title, and add tab item to tab control 
        TabItem BackGround = new TabItem(); 
        BackGround.Header = "BackGround"; 
        tabctrl.Items.Insert(1, BackGround); 
        BackGround.Height = 38; 

        //Initialize Stack Panel, set orientation, and add to tab control 
        StackPanel panel = new StackPanel(); 
        panel.Orientation = Orientation.Vertical; 
        BackGround.Content = panel; 

        //Initialize Menu Items 
        Button AddMap = new Button(); 
        Button AddDemoMap = new Button(); 
        Button RemoveMap = new Button(); 
        Button MoveSelected = new Button(); 
        Button Properties = new Button(); 
        Button ScaleBackground = new Button(); 

        //Define Button Text 
        AddMap.Content = "Add Map"; 
        AddDemoMap.Content = "Add Demo Map"; 
        RemoveMap.Content = "Remove Map"; 
        MoveSelected.Content = "Move Selected Map to Top of List"; 
        Properties.Content = "Properties"; 
        ScaleBackground.Content = "Scale Background to Pipes"; 

        AddMap.Height = 50; 
        AddDemoMap.Height = 50; 
        RemoveMap.Height = 50; 
        MoveSelected.Height = 50; 
        Properties.Height = 50; 
        ScaleBackground.Height = 50; 

        //Add Buttons to StackPanel 
        panel.Children.Add(AddMap); 
        panel.Children.Add(AddDemoMap); 
        panel.Children.Add(RemoveMap); 
        panel.Children.Add(MoveSelected); 
        panel.Children.Add(Properties); 
        panel.Children.Add(ScaleBackground); 
       } 
       break; 
+0

如果你發佈你想要的畫面是什麼樣子的截圖這將有助於。 – 2013-03-04 20:17:49

回答

6

好吧...讓我們看看:

首先,你必須學會​​思考的抽象這樣你的UI :

Wha t是一個TabControl?

這是一個小部件列表的圖形表示,其中用戶一次可以有1個活動小部件。這些小部件具有標題(標籤項文本),可見性狀態和啓用/禁用狀態。

什麼是一堆堆疊的按鈕? (工具欄,如果你想這樣稱呼它)

這是一個用戶可以在任何給定時間執行的動作列表的圖形表示。這些操作具有說明(按鈕的內容),可能是關聯的圖標或圖形圖像,以及啓用/禁用狀態。

什麼是ContextMenu或菜單?

與上面相同,它是用戶可以執行的操作列表的圖形表示。

我該如何去創建一個WPF動態TabControl?

這是支持動態兒童爲WPF的TabControl的XAML:

<Window x:Class="WpfApplication4.Window12" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window12" Height="300" Width="300"> 
    <Window.Resources> 
     <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/> 
    </Window.Resources> 
     <TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}"> 
      <TabControl.ItemContainerStyle> 
       <Style TargetType="TabItem"> 
        <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/> 
        <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/> 
        <Setter Property="Header" Value="{Binding Title}"/> 
       </Style> 
      </TabControl.ItemContainerStyle> 
     </TabControl> 
</Window> 

視圖模型:

public class TabbedViewModel: ViewModelBase 
    { 
     private ObservableCollection<TabViewModel> _items; 
     public ObservableCollection<TabViewModel> Items 
     { 
      get { return _items ?? (_items = new ObservableCollection<TabViewModel>()); } 
     } 

     private ViewModelBase _selectedItem; 
     public ViewModelBase SelectedItem 
     { 
      get { return _selectedItem; } 
      set 
      { 
       _selectedItem = value; 
       NotifyPropertyChange(() => SelectedItem); 
      } 
     } 
    } 

    public class TabViewModel: ViewModelBase 
    { 
     private string _title; 
     public string Title 
     { 
      get { return _title; } 
      set 
      { 
       _title = value; 
       NotifyPropertyChange(() => Title); 
      } 
     } 

     private bool _isEnabled; 
     public bool IsEnabled 
     { 
      get { return _isEnabled; } 
      set 
      { 
       _isEnabled = value; 
       NotifyPropertyChange(() => IsEnabled); 
      } 
     } 

     private bool _isVisible; 
     public bool IsVisible 
     { 
      get { return _isVisible; } 
      set 
      { 
       _isVisible = value; 
       NotifyPropertyChange(() => IsVisible); 
      } 
     } 
    } 

對於該示例,在TabControl的每個項目(TabItem的)將被綁定到其中一個ViewModels,那麼它只是爲每個選項卡繼承基本TabViewModel,併爲每個選項卡創建適當的DataTemplate

正如你在這個例子中看到的,我沒有在代碼中創建或操縱任何UI元素。這簡化了所有代碼,並且有助於保持邏輯和UI之間的清晰分離。 您可以將此相同的概念應用於WPF中的所有內容。

+0

你使用MVVM燈嗎?因爲我看到了一個基類在這裏 - ViewModelBase – user1221765 2013-03-04 21:53:24

+0

@ buba1947不是真的。我幾乎使用內置代碼在這裏和那裏('ViewModelBase,命令,命令,可選擇',等等等等) – 2013-03-04 21:57:50

+0

謝謝...我自己的MVVM基類,因爲我開始與MVVM光與基類是默認ViewModelBase – user1221765 2013-03-04 21:59:09