none
listview item 上放两按钮, 如何获知是按了哪个按钮 RRS feed

答案

  • Well, 你的DataTemplate是在App.xaml中实现的,所以就很难直接给出他的Click Event Handler.

    我这里给你讲一个万能的方法,在你的Item被加载之后,你可以通过可视树遍历找到你在ListViewItem中的Button对象,然后对他们两直接 += 上Click事件的处理函数。

      this.InitializeComponent();
      listview.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
      listview.Loaded += listview_Loaded;
          
      ....
      void listview_Loaded(object sender, RoutedEventArgs e)
      {
          AddEventOnButtons((sender as ListView).ItemContainerGenerator, (sender as ListView).Items.Count);
      }
      void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
      {
          AddEventOnButtons(sender as ItemContainerGenerator, e.ItemCount);
      }
      private void AddEventOnButtons(ItemContainerGenerator c, int count)
      {
          for (int i = 0; i < count; i++)
          {
              Button button1 = FindVisualChildByName<Button>(c.ContainerFromIndex(i), "Button1");
              if (button1 != null)
              {
                  button1.Click -= button1_Click;
                  button1.Click += button1_Click;
              }
              // ... same with Button1
          }
      }
      void button1_Click(object sender, RoutedEventArgs e)
      {
      }
      public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
      {
          for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
          {
              var child = VisualTreeHelper.GetChild(parent, i);
              string controlName = child.GetValue(Control.NameProperty) as string;
              if (controlName == name)
              {
                  return child as T;
              }
              else
              {
                  T result = FindVisualChildByName<T>(child, name);
                  if (result != null)
                      return result;
              }
          }
          return null;
      }

    注意,你需要给你的两个按钮分别命名为 x:Name="Button1" 和 "Button2", 因为我是根据名字在可视树中遍历的。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月21日 10:08
    版主

全部回复

  • listview item 上放两按钮, 如何获知是按了哪个按钮
    还得类似findcontrol,findname之类的方法,或者通过拆箱sender获取其name
    2012年6月20日 7:49
  • 可以说得具体点么,  private void ItemListView_ItemClick(object sender, ItemClickEventArgs e)
            {
                这里的 sender 是 listview
    2012年6月20日 8:33
  • 还有一点就是假如我的 listview item 里放   新建一个类继承 button 然后自定义的按钮   则会死程序, 但是假如只是自定义按钮则不会死. 这是为何。两者的区别只是前者有自己的类, 类里边有 protected virtual void OnPointerPressed(PointerRoutedEventArgs e)
            {

            }

            protected virtual void OnPointerReleased(PointerRoutedEventArgs e)
            {

            }仅此而已

    2012年6月20日 9:44
  • 可以说得具体点么,  private void ItemListView_ItemClick(object sender, ItemClickEventArgs e)
            {
                这里的 sender 是 listview

    ((ListView)sender).name

    你可以通过获取名称来标识你的按钮,当然也可以根据其他属性,只要可以惟一标识

    2012年6月20日 9:59
  • 我上面放了按钮的, 点击按钮, 是可以接收到 clickiterm事件,但是 selectitem返回的是空的
    2012年6月21日 3:33
  • 1. 你既然点击了ListViewItem里面的按钮,为什么不处理按钮本身的点击事件而去处理ListView的ItemClick事件。

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Button Content="button 1" Click="Button_Click_1" Margin="10"/>
                            <Button Content="button 1" Click="Button_Click_2" Margin="10"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>

    我注意到,你并没有使用数据绑定,而是直接在ListView中写了ListViewItem, 且放置了你的Button。这样你也可以直接分别处理按钮的点击事件,而不需要舍其近,求其远。

    2. 对于你自己继承Button实现的按钮类,你重载了OnPointerPressed和OnPointerReleased,但是你并没有默认调用base.OnPointerPressed(e); 和  base.OnPointerReleased(e); 所以导致你按下按钮时候,你的按钮没有默认的按钮行为。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月21日 4:19
    版主
  • Click="Button_Click_1"这个在哪实现呢
    2012年6月21日 6:46
  • <DataTemplate x:Key="WeatherListViewFrontTileTemplate">
                    <Grid Width="800" Height="76" HorizontalAlignment="Left" VerticalAlignment="Top">
                        <StackPanel Orientation="Horizontal">
                            <Button Content="{Binding We}" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Height="76" Width="400" Style="{StaticResource ButtonStyleListView}" FontSize="30" Padding="0,0,0,3" UseLayoutRounding="False">
                                <Button.Background>
                                    <ImageBrush ImageSource="We.png" Stretch="Fill"/>
                                </Button.Background>
                            </Button>
                            <Button Content="{Binding WP}" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Height="76" Width="400" Style="{StaticResource ButtonStyleListView}" FontSize="30" Padding="0,0,0,3" UseLayoutRounding="False">
                                <Button.Background>
                                    <ImageBrush ImageSource="We.png" Stretch="Fill"/>
                                </Button.Background>
                            </Button>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
    2012年6月21日 6:51
  • 错误 1 无法在应用程序类 XAML 文件中设置事件 G:\20120521_新时代\win8ProjectStudy\FlyWeather\FlyWeather\App.xaml FlyWeather加了之后有这个错误, 我这个 listview item 模板是定义在 app.xaml的, 请 Bob 给个完整的答案好吗
    2012年6月21日 7:03
  • Well, 你的DataTemplate是在App.xaml中实现的,所以就很难直接给出他的Click Event Handler.

    我这里给你讲一个万能的方法,在你的Item被加载之后,你可以通过可视树遍历找到你在ListViewItem中的Button对象,然后对他们两直接 += 上Click事件的处理函数。

      this.InitializeComponent();
      listview.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
      listview.Loaded += listview_Loaded;
          
      ....
      void listview_Loaded(object sender, RoutedEventArgs e)
      {
          AddEventOnButtons((sender as ListView).ItemContainerGenerator, (sender as ListView).Items.Count);
      }
      void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
      {
          AddEventOnButtons(sender as ItemContainerGenerator, e.ItemCount);
      }
      private void AddEventOnButtons(ItemContainerGenerator c, int count)
      {
          for (int i = 0; i < count; i++)
          {
              Button button1 = FindVisualChildByName<Button>(c.ContainerFromIndex(i), "Button1");
              if (button1 != null)
              {
                  button1.Click -= button1_Click;
                  button1.Click += button1_Click;
              }
              // ... same with Button1
          }
      }
      void button1_Click(object sender, RoutedEventArgs e)
      {
      }
      public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
      {
          for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
          {
              var child = VisualTreeHelper.GetChild(parent, i);
              string controlName = child.GetValue(Control.NameProperty) as string;
              if (controlName == name)
              {
                  return child as T;
              }
              else
              {
                  T result = FindVisualChildByName<T>(child, name);
                  if (result != null)
                      return result;
              }
          }
          return null;
      }

    注意,你需要给你的两个按钮分别命名为 x:Name="Button1" 和 "Button2", 因为我是根据名字在可视树中遍历的。

    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年6月21日 10:08
    版主