【问题标题】:Listbox SelectionChanged not working with Button in its ItemTemplateListbox SelectionChanged 无法在其 ItemTemplate 中使用 Button
【发布时间】:2013-09-23 10:59:05
【问题描述】:

当我在列表框中选择项目时,下面的代码不起作用,你知道为什么吗?

<ListBox BorderBrush="Transparent" Background="Transparent" Name="listbox" HorizontalAlignment="Center" VerticalAlignment="Center" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="selection_changed">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate> 
            <Button Height="90" Width="150" Template="{StaticResource cbutton}"/>                
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox> 

模板 cbutton 看起来像这样

 <ControlTemplate x:Key="cbutton" TargetType="Button">
            <Border CornerRadius="3" BorderThickness="3.5" BorderBrush="White">
                <Border.Background>
                    <LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
                        <GradientStop Color="DarkOrange" Offset="0.1"/>
                        <GradientStop Color="Orange" Offset="0.85"/>
                    </LinearGradientBrush>
                </Border.Background>
                <TextBlock FontWeight="ExtraBold" Foreground="White" TextAlignment="Center" TextWrapping="Wrap" FontSize="15" Text="{Binding name}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Border>
        </ControlTemplate>

【问题讨论】:

  • “不起作用”是什么意思?发生什么了?有错误吗?
  • 我通过显示类似code private void selection_changed(object sender, SelectionChangedEventArgs e) { MessageBox.Show("works?"); }code 但没有显示任何内容。
  • 您是否尝试在数据模板中使用其他控件而不是按钮?
  • 是的,我做到了。我把 textblock 和它的工作,但我想知道它的行为方式出乎意料的按钮有什么问题。

标签: c# wpf listbox selectionchanged


【解决方案1】:

SelectionChanged 事件未被触发,因为按钮是捕获鼠标点击的控件,而不是 ListBox

您可以将事件处理程序设置为按钮的单击事件。

   <Button Height="90" Width="150" Click="myClickEventHandler"/>  

无论如何,我建议您使用 MVVM,而不是 Code-Behind 事件处理程序。

您可以设置一个命令,该命令将在单击按钮时触发并将命令发送到按钮的内容,例如

  <Button Name="myButton" Height="90" Width="150" Template="{StaticResource cbutton}">     
      <i:Interaction.Triggers>
             <i:EventTrigger EventName="SelectionChanged">
                   <i:InvokeCommandAction Command="{Binding DoSomething}"  CommandParameter="{Binding ElementName=myButton, Path=Content}"/>
            </i:EventTrigger>
      </i:Interaction.Triggers>
  </Button>

视图模型

DoSomething = new DelegateCommand<object>(content=> 
{
    // Do whatever you want 

});

如果你不熟悉 MVVM,学习它需要一些时间,但绝对值得:)

【讨论】:

  • @user2396510 我很抱歉,那个答案不好,我更新了我的答案
  • @user2396510 与 WinForms 不同,WPF 事件机制有几种事件 - 从最顶层的父级到子级的事件和相反的事件。你可以了解更多here
  • 我几乎不知道 MVVM,但它似乎值得学习。谢谢。
  • @user2396510 我强烈建议您学习它。一开始可能有点困难,但一旦你做到了——你就会明白它的真正力量。我在答案here 中发布了一些关于 MVVM 的好链接
  • 有同样的问题。我没有使用按钮中的“命令”对象,而是在 Button.Tag 属性上设置了绑定(与我绑定到 Button.Content 的东西相同)并将点击事件捕获在我的 ViewModel 中(对我的 MVVM 使用 Caliburn Micro )。只是我的 2 美分。
【解决方案2】:

您可以在 ListBoxItem 上添加 PreviewMouseDown 事件处理程序:

    <ListBox ItemsSource="{Binding ListBoxItemsSource}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <EventSetter Event="PreviewMouseDown"
                             Handler="ItemOnPreviewMouseDown" />
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>


    private void ItemOnPreviewMouseDown(
        object sender, MouseButtonEventArgs e)
    {
        ((ListBoxItem) sender).IsSelected = true;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多