2010-10-19 4 views
0

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

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

}

ответ

2

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

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 элементы меню (Сохранить) являются частью оболочки приложения, а файлы, находящиеся в оболочке, находятся внутри оболочки (оболочка имеет контейнер tabcontrol, возможно, где файлы загружаются по мере их открытия). Таким образом, маршрутизированные команды (Сохранить) определяются оболочкой приложения, а все остальные страницы внутри контейнера оболочки добавляют эти команды в коллекцию привязки команд (this.CommandBindings.Add(cmdname, actionname, predicatename)), поэтому каждая страница выполняет свое соответствующее действие, и команда вызывается для них только тогда, когда они находятся в центре внимания.

+0

Спасибо, что посмотрели мою нить. Я полагаю, что ваше предложение состоит в том, чтобы определить 3 пропозиции для пункта меню в Command class Right?Вам также предлагается создать уникальный массив элементов для каждого списка. Это верно? Вы хотите определить 3 ObservableCollections для каждого списка? Будет приятно видеть любой рабочий образец. Еще раз спасибо. – vladc77

+0

Обновлено ответ – whoisthis

+0

Благодарим за обновление. Это очень близко. Мне просто нужно еще один наконечник, наконец, понять это. Посмотрите на код, который я добавил в качестве ответа. Я высоко ценю вашу помощь. – vladc77

Смежные вопросы