【问题标题】:WPF Command Binding ItemsControl in Styles样式中的 WPF 命令绑定 ItemsControl
【发布时间】:2018-11-20 09:49:37
【问题描述】:

我在Textboxstyles.xaml 中有如下样式

<Style x:Key="EmptyItemsControlUsabilityDashboard2017Style" TargetType="ItemsControl">
        <Style.Triggers>
            <Trigger Property="HasItems" Value="false">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Control">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                            <Image Height="12" Width="12" Source="/YoLo;component/Resources/Images/link.png" Margin="0,3,0,0" />
                            <TextBlock x:Name="EmptyCollectionTextBox" Text="{x:Static UsabilityDashboard2017Loc:DashboardUsability2017Resource.lblNumNotDefined}" 
                                       Style="{StaticResource UsabilityDashboard2017TextBoxStyle}"
                                       HorizontalAlignment="Center"
                                       Margin="5,25,0,25"/>
                            </StackPanel>
                    </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
 </Style>

我已经在另一个 Xaml 文件中使用了它,如下所示

 <ItemsControl ItemsSource="{Binding YoLoViewModelsCollection}" Name="YoLoViewModelsItemSource" Style="{StaticResource EmptyItemsControlUsabilityDashboard2017Style}">

现在它显示了一个文本框,该集合为空,但是如何在用户单击它执行命令的样式内的名为“EmptyCollectionTextBox”的文本块上设置命令绑定?

我已经看到了自定义命令,但不知何故它们不起作用。

【问题讨论】:

  • 可能是this helps
  • @dymanoid 感谢您的链接,但不是真的。我需要在 Style 中做到这一点
  • 我看不到文本框。你是说文本块吗? TextBlock 没有命令属性,所以再一次;你想完成什么?
  • 对不起,我不明白你的问题。默认情况下,TextBlock 不可点击,但您可以为其处理 MouseLeftButtonEvent。

标签: wpf xaml command styles


【解决方案1】:

这段代码实际上有很多问题。首先我不知道那个触发器应该做什么,看起来只有当列表中没有元素时才会设置控件模板?

其次,您似乎正试图用图像和文本来表示集合中的每个元素,所有这些都在 ItemsControl 中。您不能通过模板化整个控件来做到这一点,而是通过模板化 ItemTemplate 来做到这一点。而且您使用的是 DataTemplate,而不是 ControlTemplate:

现在回到您的实际问题,您希望在单击 TextBlock 时得到通知。有许多不同的方法可以做到这一点,但在这种情况下,您最好将 TextBlock 替换为 Button,然后使用将其表示为 TextBlock 的 ControlTemplate 覆盖模板。这为您提供了两全其美:从 GUI 的角度来看,它实际上仍然是一个 TextBlock,但您仍然可以获得所有按钮单击通知和命令处理程序等:

<Image />

<Button Command="{Binding ClickedCommand}" Cursor="Hand">
    <Button.Template>
        <ControlTemplate>
            <TextBlock Text="Text Binding Goes Here" />
        </ControlTemplate>
    </Button.Template>
</Button>

此特定示例假定您的集合中的项目有一个名为“ClickedCommand”的命令处理程序。在实践中,您的处理程序可能驻留在父类中(例如主窗口的视图模型),在这种情况下,您需要给您的主窗口 ax:Name(例如“_this”)并绑定到它,将项目传入作为 CommandParameter 所以它知道哪个被点击了:

<Button Command="{Binding ElementName=_this, Path=DataContext.ClickedCommand}" CommandParameter="{Binding}" Cursor="Hand">

然后你的主视图模型有一个看起来像这样的处理程序:

    public ICommand ClickedCommand { get { return new RelayCommand<YourCollectionItemType>(OnClicked); } }
    private void OnClicked(YourCollectionItemType item)
    {
    }

【讨论】:

  • 只有在列表中没有元素的情况下才会设置控件模板? => 是的,这是正确的
  • 是的,但是我想将所有这些都移到样式中,所以我可以在样式中进行绑定吗?
  • 好的,在这种情况下,只需使用 &lt;Button Command="{Binding ElementName=_this, Path=DataContext.ClickedCommand}" Cursor="Hand"&gt; 并将 ControlTemplate 设置为您的 TextBlock。
猜你喜欢
  • 2021-11-05
  • 2010-11-06
  • 1970-01-01
  • 2017-01-31
  • 2015-12-09
  • 2016-08-12
  • 2012-03-18
  • 2016-06-04
  • 1970-01-01
相关资源
最近更新 更多