代码之家  ›  专栏  ›  技术社区  ›  user134363

MVVM-在一个对象列表中,每个对象都包含一个命令,我如何才能得到合适的命令来触发?

  •  1
  • user134363  · 技术社区  · 16 年前

    也许我用了错误的方法来处理这个问题,但是在我的视图模型中,我有一个对象列表(cgcapswitchboarditem),每个对象都包含一个DelegateCommand属性。我在这里的意图是,我的列表中的每个项(cgcapswitchboarditem)将表示我的解决方案中的一个模块,通过调用该命令将加载一个模块。或者,更好地说,我正在使用这个列表来构建一个按钮或菜单项列表,当选中时,这些按钮或菜单项将打开所请求的视图。

    我遇到的问题是,最后一个cgcapswitchboarditem命令是不管按下了什么按钮都会被触发的命令。我已经通过以不同的顺序添加它们来测试了这一点,无论最后添加的是哪个,都会触发命令。我怎样才能得到适当的开火命令?

    编辑:我把问题缩小了范围,不知道该怎么办。问题出现在我将泛型函数分配给RunMethod时创建的函数中。如果您查看下面的代码,我将在创建cgcapswitchboarditem类时分配RunMethod。如果你看看我的泛型函数,我将传入itm.ModuleName属性。显然,新创建的委托,即我分配给RunMethod的委托,正在保留对itm.ModuleName的引用,而不是我想要的字符串值。因为这是在循环中,所以itm变量仍然设置为列表中的最后一个模块。因此,当调用RunMethod()时,它引用itm.ModuleName而不是“MyModuleName”。有什么想法吗?

    public class CGCAppSwitchboardItem : ISwitchboardItem
    {                
        public Action RunMethod { get; set; } //RunMethod gets assigned by external ViewModel
    
        public ICommand ExecuteCommand { get; set; }
    
        public CGCAppSwitchboardItem()
        {
            ExecuteCommand = new DelegateCommand<object>(
                o =>
                {                   
                    if (RunMethod != null)
                    {
                        RunMethod();
                    }
                }, 
                o =>
                {
                    return (RunMethod != null);
                });
        }               
    } 
    
    
    public class CGCApplicationShellViewModel : ICGCApplicationShellViewModel, INotifyPropertyChanged, ISwitchboardListContainer
    {
    

    //…为了简洁起见删除了代码 私有void PopulateSwitchboardItems() 如果(_moduleCatalog!=空) { _开关板项目。清除();

                foreach (var itm in _moduleCatalog.Modules)
                {
                    _switchBoardItems
                        .Add(
                            new CGCAppSwitchboardItem()
                                {
                                    Name = itm.ModuleName,
                                    RunMethod = () => 
                                     {
    

    System.Windows.Forms.MessageBox.Show(itm.ModuleName); _moduleManager.LoadModule(itm.ModuleName); //_moduleManager.LoadModule(“ATimesheetModule”); } ); } } }

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:WTSSwitchBrdItm="clr-namespace:WTS.CGCApplicationInterface.Switchboard"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="150">
    <UserControl.Resources>
        <DataTemplate x:Key="ShowModule">
            <Button Name="btnOpenView" Height="Auto" HorizontalAlignment="Left" VerticalAlignment="Top" Width="Auto"
                    Command="{Binding ExecuteCommand}">                
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="35" />
                        <RowDefinition Height="15" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Image x:Name="imgAvatar" Source="{Binding Path=Avatar}" Grid.Column="0" Grid.Row="0" Width="50" Height="50"/>
                    <TextBlock x:Name="txtName" Text="{Binding Path=Name}" Grid.Column="1" Grid.Row="0" />
                    <TextBlock x:Name="txtDescription" Margin="0, 5, 0, 5" Grid.Column="1" Grid.Row="3" >
                    <TextBlock.Text>
                        <MultiBinding StringFormat=" ({0})">
                            <Binding Path="Description"/>                  
    
                        </MultiBinding>
                    </TextBlock.Text>
                    </TextBlock>
                </Grid>
            </Button>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Path=SwitchboardItems}" ItemTemplate="{StaticResource ShowModule}"></ListBox>
    </Grid> </UserControl>
    
    1 回复  |  直到 16 年前
        1
  •  0
  •   Jerry Nixon    16 年前

    您可以包括CommandParameter来标识记录:

    <Button Command="{Binding ExecuteCommand}" CommandParameter="{Binding RecordId}" />
    
    推荐文章