Динамическое меню WPF, связанное с объектом? - PullRequest
0 голосов
/ 19 октября 2010

Я хотел бы иметь возможность создавать динамические меню, связанные с определенным объектом.Допустим, у меня будет 3 контейнера списка с одним стилем, где у меня также есть Меню.Мне нужно сгенерировать различные пункты меню из коллекции команд RoutetUIC относительно каждого списка.Я пытался решить эту загадку, но занял у меня какое-то время и все еще не могу заставить ее работать.Мне нужно генерировать специфичные для объекта меню, уникальное меню для каждого списка.Любые идеи высоко ценятся.Спасибо!

XAML:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="DynamicMenu.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>

    <Style x:Key="ListViewStyleTask" TargetType="{x:Type ListView}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListView}">
                    <Grid>
                        <Menu x:Name="mainMenu">
                            <MenuItem x:Name="menuItem" Header="Tasks" ItemsSource="{Binding Commands}" >
                                <MenuItem.ItemContainerStyle>
                                    <Style TargetType="{x:Type MenuItem}">
                                        <Setter Property="Command" Value="{Binding}" />
                                        <Setter Property="Header" Value="{Binding Path=Text}" />
                                        <Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
                                    </Style>
                                </MenuItem.ItemContainerStyle>
                            </MenuItem>
                        </Menu>
                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>

<Grid x:Name="LayoutRoot">
    <ListView x:Name="Container1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
        <ListView.View>
            <GridView>
                <GridViewColumn/>
            </GridView>
        </ListView.View>
    </ListView>
    <ListView x:Name="Container2" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
        <ListView.View>
            <GridView>
                <GridViewColumn/>
            </GridView>
        </ListView.View>
    </ListView>
    <ListView x:Name="Container3" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
        <ListView.View>
            <GridView>
                <GridViewColumn/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

I have added some commands which I need to associate to 3 different Listviews:

    public partial class MainWindow : Window
{

    // Container 1
    public static RoutedUICommand NameCommand = new RoutedUICommand("Name", "NameCommand", typeof(MainWindow));
    public static RoutedUICommand StreetCommand = new RoutedUICommand("Street", "StreetCommand", typeof(MainWindow));
    public static RoutedUICommand GroupCommand = new RoutedUICommand("Add to Group", "AddGroup", typeof(MainWindow));

    // Container 2
    public static RoutedUICommand ViewDetailsCommand = new RoutedUICommand("View Details", "ViewDetailsCommand", typeof(MainWindow));

    // Container 3
    public static RoutedUICommand StartCommand = new RoutedUICommand("Start", "StartCommand", typeof(MainWindow));
    public static RoutedUICommand StopCommand = new RoutedUICommand("Stop", "StopCommand", typeof(MainWindow));
    public static RoutedUICommand LoadCommand = new RoutedUICommand("Load", "LoadCommand", typeof(MainWindow));

    public MainWindow()
    {
        this.InitializeComponent();

        // Insert code required on object creation below this point.
    }
}

}

1 Ответ

2 голосов
/ 19 октября 2010

Вам необходимо определить структуру для группировки данных, как вам нужно в вашем шаблоне управления. Как то так,

public class CommandCollection {
    public ObservableCollection<Command> Commands { get; set; }
}

public class Command {

    public ICommand Action { get; set; }

    public string Text { get; set; }

    public string Parameter { get; set; }
}

Имеют 3 члена CommandCollection, каждый из которых имеет свои команды, а затем назначает их в качестве datacontext для ListViews

Обновлено

После объявления вышеуказанной структуры вы объявляете 3 члена,

public CommandCollection Container1Commands { get; set; }

public CommandCollection Container2Commands { get; set; }

public CommandCollection Container3Commands { get; set; }

Заполните эти элементы,

    Container1Commands = new CommandCollection ();
    Container1Commands.Commands = new ObservableCollection<CommandParameters> ();
    Container1Commands.Commands.Add (new CommandParameters () { Action = NameCommand, Text = "Name" });
    Container1Commands.Commands.Add (new CommandParameters () { Action = StreetCommand, Text = "Street" });
    Container1Commands.Commands.Add (new CommandParameters () { Action = GroupCommand, Text = "Group" });

    Container2Commands = new CommandCollection ();
    Container2Commands.Commands = new ObservableCollection<CommandParameters> ();
    Container2Commands.Commands.Add (new CommandParameters () { Action = ViewDetailsCommand, Text = "ViewDetails" });

    Container3Commands = new CommandCollection ();
    Container3Commands.Commands = new ObservableCollection<CommandParameters> ();
    Container3Commands.Commands.Add (new CommandParameters () { Action = StartCommand, Text = "Start" });
    Container3Commands.Commands.Add (new CommandParameters () { Action = StopCommand, Text = "Stop" });
    Container3Commands.Commands.Add (new CommandParameters () { Action = LoadCommand, Text = "Load" });

Установить контекст данных,

    this.DataContext = this;
    this.Container1.DataContext = Container1Commands;
    this.Container2.DataContext = Container2Commands;
    this.Container3.DataContext = Container3Commands;

Обновите шаблон управления, указав привязку команды пункта меню,

<Setter Property="Command" Value="{Binding Action}" />

Обновлено XAML

    <Window.Resources>

        <Style x:Key="ListViewStyleTask" TargetType="{x:Type ListView}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListView}">
                        <Grid>
                            <Menu x:Name="mainMenu" >
                                <MenuItem x:Name="menuItem" Header="Tasks" ItemsSource="{Binding Commands}">
                                    <MenuItem.ItemContainerStyle>
                                        <Style TargetType="{x:Type MenuItem}">
                                            <Setter Property="Command" Value="{Binding Action}" />
                                            <Setter Property="Header" Value="{Binding Path=Text}" />
                                            <Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
                                        </Style>
                                    </MenuItem.ItemContainerStyle>
                                </MenuItem>
                            </Menu>
                        </Grid>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ListView
            Grid.Row="0" x:Name="Container1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
            <ListView.View>
                <GridView>
                    <GridViewColumn/>
                </GridView>
            </ListView.View>
        </ListView>
        <ListView
            Grid.Row="1" x:Name="Container2" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
            <ListView.View>
                <GridView>
                    <GridViewColumn/>
                </GridView>
            </ListView.View>
        </ListView>
        <ListView
            Grid.Row="2" x:Name="Container3" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
            <ListView.View>
                <GridView>
                    <GridViewColumn/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

Код позади

// Container 1
public static RoutedUICommand NameCommand = new RoutedUICommand ("Name", "NameCommand", typeof (Window1));
public static RoutedUICommand StreetCommand = new RoutedUICommand ("Street", "StreetCommand", typeof (Window1));
public static RoutedUICommand GroupCommand = new RoutedUICommand ("Add to Group", "AddGroup", typeof (Window1));

// Container 2
public static RoutedUICommand ViewDetailsCommand = new RoutedUICommand ("View Details", "ViewDetailsCommand", typeof (Window1));

// Container 3
public static RoutedUICommand StartCommand = new RoutedUICommand ("Start", "StartCommand", typeof (Window1));
public static RoutedUICommand StopCommand = new RoutedUICommand ("Stop", "StopCommand", typeof (Window1));
public static RoutedUICommand LoadCommand = new RoutedUICommand ("Load", "LoadCommand", typeof (Window1));

public Window1 () {
    InitializeComponent ();
    this.Loaded += new RoutedEventHandler (Window1_Loaded);
}

public CommandCollection Container1Commands { get; set; }

public CommandCollection Container2Commands { get; set; }

public CommandCollection Container3Commands { get; set; }

void Window1_Loaded (object sender, RoutedEventArgs e) {
    Container1Commands = new CommandCollection ();
    Container1Commands.Commands = new ObservableCollection<Command> ();
    Container1Commands.Commands.Add (new Command () { Action = NameCommand, Text = "Name" });
    Container1Commands.Commands.Add (new Command () { Action = StreetCommand, Text = "Street" });
    Container1Commands.Commands.Add (new Command () { Action = GroupCommand, Text = "Group" });

    Container2Commands = new CommandCollection ();
    Container2Commands.Commands = new ObservableCollection<Command> ();
    Container2Commands.Commands.Add (new Command () { Action = ViewDetailsCommand, Text = "ViewDetails" });

    Container3Commands = new CommandCollection ();
    Container3Commands.Commands = new ObservableCollection<Command> ();
    Container3Commands.Commands.Add (new Command () { Action = StartCommand, Text = "Start" });
    Container3Commands.Commands.Add (new Command () { Action = StopCommand, Text = "Stop" });
    Container3Commands.Commands.Add (new Command () { Action = LoadCommand, Text = "Load" });

    this.CommandBindings.Add (new CommandBinding (NameCommand, ExecuteNameCommand, CanExecuteNameCommand));
    this.CommandBindings.Add (new CommandBinding (StreetCommand, ExecuteStreetCommand, CanExecuteStreetCommand));
    this.CommandBindings.Add (new CommandBinding (GroupCommand, ExecuteGroupCommand, CanExecuteGroupCommand));

    this.DataContext = this;
    this.Container1.DataContext = Container1Commands;
    this.Container2.DataContext = Container2Commands;
    this.Container3.DataContext = Container3Commands;
}

private void ExecuteNameCommand (object inSender, RoutedEventArgs inE) {
    MessageBox.Show ("Name command Executed");
}

private void CanExecuteNameCommand (object inSender, CanExecuteRoutedEventArgs inE) {
    inE.CanExecute = true;
}

private void ExecuteStreetCommand (object inSender, RoutedEventArgs inE) {
    MessageBox.Show ("Street command Executed");
}

private void CanExecuteStreetCommand (object inSender, CanExecuteRoutedEventArgs inE) {
    inE.CanExecute = true;
}

private void ExecuteGroupCommand (object inSender, RoutedEventArgs inE) {
    MessageBox.Show ("Group command Executed");
}

private void CanExecuteGroupCommand (object inSender, CanExecuteRoutedEventArgs inE) {
    inE.CanExecute = true;
}

Другие классы

public class CommandCollection {

    public ObservableCollection<Command> Commands { get; set; }
}

public class Command {

    public ICommand Action { get; set; }

    public string Text { get; set; }

    public string Parameter { get; set; }
}

Надеюсь, теперь у вас все получилось.

Обновлено для описания RoutedUICommand, Идея должна заключаться в том, чтобы эти пункты меню находились во внешнем контейнере (например, в оболочке), в котором были бы другие страницы (например, фрейм / холст), например, если вы видите MS Visual Studio, пункты меню (Сохранить) являются частью оболочка приложения и файлы openeed находятся внутри оболочки (возможно, оболочка имеет контейнер tabcontrol, где файлы загружаются при их открытии). Таким образом, перенаправленные команды (Сохранить) определяются оболочкой приложения, и все остальные страницы внутри контейнера оболочки добавляют эти команды в свою коллекцию привязок команд (this.CommandBindings.Add(cmdname, actionname, predicatename)), поэтому каждая страница выполняет свое собственное соответствующее действие, и команда вызывается для них. только когда они в фокусе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...