【问题标题】:Command binding not working in WPF with prism命令绑定在带有棱镜的 WPF 中不起作用
【发布时间】: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(){ }           
         }
     }
    

【问题讨论】:

    标签: c# wpf xaml data-binding prism


    【解决方案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 您的输出窗口中是否有任何绑定错误?
    猜你喜欢
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多