3

それでは本題です。3 つのパネルに分割されたウィンドウがあります。中央には描画面が含まれ、左側にはタブ コントロールが含まれています。タブ コントロールのタブは、右側のパネルに新しいメニューを開く必要があるボタンのリストで構成されています。コードでこれを行う方法がわからないので、実行時に C# で各ボタンを個別に作成することにしました。それについてもっと良い方法が必要なようです。現在、ボタン クリック イベントに対して以下の関数を呼び出して、実行時に「tabctrl」という名前の TabControl の右側のパネルにさまざまなメニューを描画します。描画するメニューのセットを指定するには文字列引数が必要ですが、この時点ではメニューの 1 つのコードしか記述していません。以下は、関数と xml のコードです。これについてもっと良い方法はありますか?

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

1 に答える 1

6

わかりました...見てみましょう:

まず、UI を抽象的な方法で考える方法を学ぶ必要があります。

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) が ViewModel の 1 つにバインドされます。その後は、各タブのベース TabViewModel を継承し、それぞれに適切なタブを作成するだけDataTemplateです。

この例でわかるように、コードで UI 要素を作成したり操作したりすることは決してありません。これにより、すべてのコードが大幅に簡素化され、ロジックと UI を明確に分離することができます。これと同じ概念を WPF のすべてに適用できます。

于 2013-03-04T20:33:31.133 に答える