【问题标题】:Getting selected item in ItemsControl在 ItemsControl 中获取所选项目
【发布时间】:2013-08-29 16:37:51
【问题描述】:

我有以下代码以行和列的形式填充我的用户控件。正在填充的用户控件包含按钮、链接、文本框等。当在特定行/列中的特定用户控件上按下某个按钮时,我需要知道该按钮被按下的是哪个用户控件。这是在行和列中填充用户控件的 XAML

  <ItemsControl ItemsSource="{Binding Templates}" Width="{Binding GridWidth}">
        <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                    <UniformGrid Columns="{Binding NumColumns}" />
              </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
              <ItemsControl.ItemContainerStyle>
                 <Style>
                     <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" />
                     <Setter Property="Grid.Row" Value="{Binding RowIndex}" />
                  </Style>
                 </ItemsControl.ItemContainerStyle>
                 <ItemsControl.ItemTemplate>
  </ItemsControl>

模板基本上是在行/列中填充的用户控件的集合。 最好我想在 ViewModel 中执行此操作,但现在代码中的解决方案也可以。

【问题讨论】:

  • ItemsControl 不跟踪所选项目。如果您想要这种行为,请使用 ListBox 之类的内容并覆盖模板,例如 this

标签: wpf xaml binding


【解决方案1】:

我有一个解决方案给你...一种行为:

   public static class SelectedItemBehavior
   {
      public static readonly DependencyProperty BindingProperty =
         DependencyProperty.RegisterAttached("Binding", typeof(object), typeof(SelectedItemBehavior),
            new FrameworkPropertyMetadata(new object(),
               FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
               SelectedItem_Changed));

      public static object GetBinding(FrameworkElement frameworkElement)
      {
         return (object)frameworkElement.GetValue(BindingProperty);
      }

      public static void SetBinding(FrameworkElement frameworkElement, object value)
      {
         frameworkElement.SetValue(BindingProperty, value);
      }

      private static void SelectedItem_Changed(Object sender, DependencyPropertyChangedEventArgs e)
      {
         ToggleButton toggleButton = (ToggleButton)sender;
         toggleButton.Checked -= ToggleButtonOnChecked;
         toggleButton.IsChecked = e.NewValue?.Equals(toggleButton.DataContext) ?? false;
         toggleButton.Checked += ToggleButtonOnChecked;
      }

      private static void ToggleButtonOnChecked(object sender, RoutedEventArgs e)
      {
         ToggleButton toggleButton = (ToggleButton)sender;
         SetBinding(toggleButton, toggleButton.DataContext);
      }
   }

然后绑定如下:

    <ItemsControl
        Name="ItemsControlList"
        Width="200"
        Height="100"
        ItemsSource="{Binding Values}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <RadioButton local:SelectedItemBehavior.Binding="{Binding ElementName=ItemsControlList, Path=DataContext.SelectedValue}" Content="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

【讨论】:

    【解决方案2】:

    ItemsControl 不能选择项目,只能显示集合。只有Selector 或其后代之一可以选择项目。

    对于您的场景,我认为 ListViewGridView 会适合。当用户单击该行中的控件时,该事件将冒泡到ListView,并且该项目将被选中。您可以覆盖默认样式,使其不会显示为选定行:WPF ListView turn off selection

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多