MVVM中ItemsControl内的EventTrigger无法工作

3

我希望在MVVM中动态绑定多个按钮。
1. 我使用ItemControl动态创建了按钮。
2. 但是,它没有触发点击事件。请帮助我解决这个问题。

        <ItemsControl ItemsSource="{Binding ComponentList,Mode=TwoWay}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Button Tag="{Binding WorkFlowCompId}">
                                <Button.Content>
                                    <TextBlock Text="{Binding ComponentName,Mode=TwoWay}"/>
                                </Button.Content>
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="Click">
                                        <i:InvokeCommandAction Command="{Binding ComponentSelected}" 
CommandParameter="{Binding WorkFlowCompId,Mode=TwoWay}" >
                                        </i:InvokeCommandAction>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </Button>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

这个 i:Interaction.Triggers 是什么? - Stephen Chung
代码乍一看没问题。尝试检查该命令是否绑定到InvokeCommandAction并从ItemsSource中移除双向绑定模式。 - Vladimir Dorokhov
组件选择是在项目还是父级上进行的? - Derek Beattie
这里提供了几种解决方案:http://stackoverflow.com/questions/6085846/mvvm-light-commands-within-an-itemscontrol?answertab=votes#tab-top - Joris
显示剩余2条评论
2个回答

6
您的问题在于该命令从其模板获取上下文,因此无法访问ViewModel的根。将此类添加到您的解决方案中:

您的问题在于该命令从其模板获取上下文,因此无法访问ViewModel的根。将此类添加到您的解决方案中:

public class DataContextProxy : FrameworkElement
    {
        public DataContextProxy()
        {
            this.Loaded += new RoutedEventHandler(DataContextProxyLoaded);
        }

        void DataContextProxyLoaded(object sender, RoutedEventArgs e)
        {
            Binding binding = new Binding();
            if (!String.IsNullOrEmpty(BindingPropertyName))
            {
                binding.Path = new PropertyPath(BindingPropertyName);
            }
            binding.Source = this.DataContext;
            binding.Mode = BindingMode;
            this.SetBinding(DataContextProxy.DataSourceProperty, binding);
        }

        public Object DataSource
        {
            get { return (Object)GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }

        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);


        public string BindingPropertyName { get; set; }

        public BindingMode BindingMode { get; set; }

    }

然后在您的XAML中使用它,如下所示:

 <UserControl.Resources>
            <library:DataContextProxy x:Key="DataContextProxy"/>
    </UserControl.Resources>

然后在您的命令绑定中:

<Button Tag="{Binding WorkFlowCompId}">
                                <Button.Content>
                                    <TextBlock Text="{Binding ComponentName,Mode=TwoWay}"/>
                                </Button.Content>
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="Click">
                                        <i:InvokeCommandAction Command="{Binding DataSource.ComponentSelected, Source={StaticResource DataContextProxy}" 
CommandParameter="{Binding WorkFlowCompId,Mode=TwoWay}" >
                                        </i:InvokeCommandAction>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </Button>

0

首先,你的Xaml应该长成这个样子:

        <ItemsControl ItemsSource="{Binding ComponentList}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Command="{Binding SelectComponent}">
                        <TextBlock Text="{Binding ComponentName}"/>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

我怀疑正如Derek在评论中所提到的,您在容器上有一个ComponentSelected命令。然而,您应该将此命令移动到组件的视图模型中。请注意,我还将其重命名为SelectComponent,以便它听起来像一个操作而不是一个属性。

双向绑定已被删除,在这种情况下它不会做任何事情。从简单绑定中分配标记值应该引起警报,表明设计存在一些问题。

顺便说一下,既然您正在进行一种选择形式,那么在这种情况下使用ListBox是否更合适呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接