EventTrigger not working inside ItemsControl in MVVM

[亡魂溺海] 提交于 2019-12-10 21:24:33

问题


I want to bind multiple buttons dynamically in MVVM.
1.I Dynamically created buttons using ItemControl
2. It did not Invoke Trigger Click Event. Please help me on this.

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

回答1:


Your problem is that the command is getting the context from its template and there it cannot access the root of the ViewModel. Add this class to your solution:

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

    }

then use it in you XAML like so:

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

Then in your command binding:

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



回答2:


A first pass at what you Xaml should look like:-

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

I suspect as Derek alludes to in his comment you have a ComponentSelected command on the container. However you should move this command ot the view model for the component. Note I've also renamed it to SelectComponent so that is sounds like an action rather than a property.

TwoWay binding has been removed it wouldn't be doing anything in this case. Assigning a Tag value from a simple binding should be setting off alarm bells that the design is having some problems.

BTW, since you are doing a form of selection would not a ListBox be more appropriate in this case?



来源:https://stackoverflow.com/questions/5576487/eventtrigger-not-working-inside-itemscontrol-in-mvvm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!