命令绑定在带有棱镜的 WPF 中不起作用

Posted

技术标签:

【中文标题】命令绑定在带有棱镜的 WPF 中不起作用【英文标题】:Command binding not working in WPF with prism 【发布时间】:2021-09-07 07:13:21 【问题描述】:

使用 Prism 库的 WPF MVVM 模式中的事件绑定不适用于子用户控件中的按钮。

我有一个基本视图PreparationMockView,其中有一个内容控件,它是一个子视图LeftBarPrepMockView。现在单击LeftBarPrepMockView 中的按钮时,不会触发SelectedTaskCommand

下面是父视图和子视图以及各自的视图模型。

父视图:

 <UserControl x:Class="PreparationMockUp.Views.PreparationMockView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mvvm="http://prismlibrary.com/"
             xmlns:preparationMockUp="clr-namespace:PreparationMockUp"
             mvvm:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d">
     <Grid>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="200" />
             <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <ContentControl Grid.Row="0" Grid.Column="0" mvvm:RegionManager.RegionName="x:Static preparationMockUp:PreparationMockUpModule.LeftBarPreparationRegionName" />
         <TabControl Grid.Row="0" Grid.Column="1" TabStripPlacement ="Left" Background="#f2f2f3">
     <Grid>
 <UserControl>

子视图:

 <UserControl x:Class="PreparationMockUp.Views.LeftBarPrepMockView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mvvm="http://prismlibrary.com/"
             mvvm:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d">
         <Grid Background="#1a2231">
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"/>
             <RowDefinition Height="*"/>
         </Grid.RowDefinitions>
         <StackPanel Grid.Row="1">
         <!-- Bind Rows using the default StackPanel for the ItemsPanel -->
             <ItemsControl Name="taskDisplayList" ItemsSource="Binding TaskList, Mode=TwoWay">
             <!-- Set the Template for each row to a TextBlock and another ItemsControl -->
                 <ItemsControl.ItemTemplate>
                 <DataTemplate>
                         <Grid Margin="5">
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="20" />
                                 <ColumnDefinition Width="*" />
                             </Grid.ColumnDefinitions>
                                 <Button Name="SelectTaskButton" Grid.Column="1" Command="Binding SelectedTaskCommand" 
                                     CommandParameter="Binding" IsEnabled="Binding IsEnabled, Mode= TwoWay" 
                                     BorderThickness ="0" HorizontalAlignment="Left" 
                                     Style="StaticResource TaskButton"
                                     Content="Binding Name">
                             </Button>
                         </Grid>
                 </DataTemplate>
             </ItemsControl.ItemTemplate>
         </ItemsControl>
         </StackPanel>
     </Grid>
 <UserControl>

视图模型:

 namespace PreparationMockUp.ViewModels
 
     public class LeftBarPrepMockViewModel : ViewModelBase
     
         private readonly IEventAggregator _eventAggregator;
         private Tasks tasks;
         readonly string path = ConfigurationManager.AppSettings["ConfigPath"].ToString();

         public LeftBarPrepMockViewModel(IEventAggregator ea)
         
             _eventAggregator = ea;
             _eventAggregator.GetEvent<PubSubEvent<PubSubMessages>>().Subscribe((message) => InsertedCylinder(),
                 ThreadOption.UIThread, true, x => x.Equals(PubSubMessages.InsertedBuildCylinder));
             SelectedTaskCommand = new DelegateCommand(NavigateToSelectedTask);
         

         public ICommand SelectedTaskCommand  get; set; 

         private List<Task> _taskList;
         public List<Task> TaskList 
          
             get 
             
                 return _taskList;
             
             set
             
                 _taskList = value;
                 OnPropertyChanged(new PropertyChangedEventArgs("TaskList"));
              
         
         private void NavigateToSelectedTask()            
     
 

【问题讨论】:

【参考方案1】:

您将SelectedTaskCommand 绑定到名为root 的元素,但它在您的代码中不存在。

Command="Binding SelectedTaskCommand, ElementName=root"

假设您指的是名为 taskDisplayListItemsControl。然后您可以使用ElementName 创建绑定,但您仍然需要引用该元素的DataContext 才能绑定到视图模型。否则绑定将搜索控件本身的属性,该属性不存在。

Command="Binding DataContext.SelectedTaskCommand, ElementName=taskDisplayList"

另一种方法是使用RelativeSource 绑定LeftBarPrepMockView 用户控件。

Command="Binding DataContext.SelectedTaskCommand, RelativeSource=RelativeSource AncestorType=x:Type local:LeftBarPrepMockView" 

您当然也可以使用绑定到ItemsControl 或其他控件,而无需ElementName

【讨论】:

@RamakrishnaReddy 您的输出窗口中是否有任何绑定错误?

以上是关于命令绑定在带有棱镜的 WPF 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

鼠标滚动在带有 wpf 数据网格和其他 UI 元素的滚动查看器中不起作用

Shell BackButtonBehavior 命令绑定在 UWP 中不起作用

为啥此模型绑定在 Razor 页面中不起作用

棱镜 IRegionNavigationJournal.GoBack 不起作用

WPF双向绑定不起作用

按钮上的绑定命令不起作用wpf mvvm