1

I have many TabItems in my MainWindow.xaml.cs They are all with the same structures. This is one of them.

<TabItem Name="tabFeatured" Header="Featured" DataContext="{Binding TemplatesFeatured}">
            <ScrollViewer>
                <ItemsControl Name="ItemsControlFeatured" ItemsSource="{Binding}" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button 
                                Name="Featured"
                                Tag="{Binding Id}"
                                Click="Button_Download_Click">
                            </Button>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </ScrollViewer>
        </TabItem>

and this is from c#

private void Button_Download_Click(object sender, RoutedEventArgs e)
{
    Button b = (Button)sender;

    string buttonTag = b.Tag.ToString();
    string categoryName = b.Name.ToLower();
}

How can I take the TabItem's Name of the clicked button, so I can use its DataContext.

Every tabitem has different Context and I want to get it, depends on the button's Name.

har07
  • 88,338
  • 12
  • 84
  • 137
gneric
  • 3,457
  • 1
  • 17
  • 30
  • Try `FindParent` from here: https://stackoverflow.com/questions/636383/how-can-i-find-wpf-controls-by-name-or-type/636456#636456 – dbc Jun 13 '15 at 22:37
  • It's not conformable with my code can't cast my List to List . I tried the second post too still can't run. I get this exception: Unable to cast object of type 'WhereSelectEnumerableIterator`2[..TemplateViewModel]' to type 'System.Collections.Generic.List`1[..TemplateViewModel]'. – gneric Jun 13 '15 at 23:01

2 Answers2

0

Try this

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Featured.Click += new EventHandler(Button_Download_Click);
            button2.Click += new EventHandler(Button_Download_Click);
            button3.Click += new EventHandler(Button_Download_Click);
        }
        string XML =
            "<Root>\n" +
            "<TabItem Name=\"tabFeatured\" Header=\"Featured\" DataContext=\"{Binding TemplatesFeatured}\">\n" +
               "<ScrollViewer>\n" +
                   "<ItemsControl Name=\"ItemsControlFeatured\" ItemsSource=\"{Binding}\">\n" +
                        "<ItemsControl.ItemsPanel>\n" +
                             "<ItemsPanelTemplate>\n" +
                                  "<WrapPanel/>\n" +
                             "</ItemsPanelTemplate>\n" +
                        "</ItemsControl.ItemsPanel>\n" +
                        "<ItemsControl.ItemTemplate>\n" +
                           "<DataTemplate>\n" +
                              "<Button Name=\"Featured\" Tag=\"{Binding Id}\" Click=\"Button_Download_Click\"></Button>\n" +
                           "</DataTemplate>\n" +
                        "</ItemsControl.ItemTemplate>\n" +
                   "</ItemsControl>\n" +
                "</ScrollViewer>\n" +
            "</TabItem>\n" +
            "<TabItem Name=\"tabFeatured\" Header=\"Featured\" DataContext=\"{Binding TemplatesFeatured}\">\n" +
               "<ScrollViewer>\n" +
                   "<ItemsControl Name=\"ItemsControlFeatured\" ItemsSource=\"{Binding}\">\n" +
                        "<ItemsControl.ItemsPanel>\n" +
                             "<ItemsPanelTemplate>\n" +
                                  "<WrapPanel/>\n" +
                             "</ItemsPanelTemplate>\n" +
                        "</ItemsControl.ItemsPanel>\n" +
                        "<ItemsControl.ItemTemplate>\n" +
                           "<DataTemplate>\n" +
                              "<Button Name=\"xxxx\" Tag=\"{Binding Id}\" Click=\"Button_Download_Click\"></Button>\n" +
                           "</DataTemplate>\n" +
                        "</ItemsControl.ItemTemplate>\n" +
                   "</ItemsControl>\n" +
                "</ScrollViewer>\n" +
            "</TabItem>\n" +
            "</Root>\n";

        private void Button_Download_Click(object sender, EventArgs e)
        {
            var button = sender as Button;

            string buttonName = button.Name;
            XDocument doc = XDocument.Parse(XML);

            List<XElement> TabItems = doc.Descendants("TabItem").ToList();

            var xmlButton = TabItems.Select(x => x).Where(y => y.Descendants("Button").FirstOrDefault().Attribute("Name").Value == buttonName).FirstOrDefault().Attribute("Name").Value;
        }
    }


}
​
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • And what does "this" does? An answer where the code is actually explained is way more helpful than just simple code snippet. Plus usually "code only" answers are marked as low quality. – PiotrWolkowski Jun 14 '15 at 02:14
  • 1
    Also, the question is about WPF and your solution is WinForms. The code in the question isn't an XML but XAML that describes a UI of the application. – PiotrWolkowski Jun 14 '15 at 02:18
  • Actually working code is the best answer. The question was about parsing XML and it doesn't matter that it is a Winform or a WPF. The answer is a high quality answer that get exactly what the user wants. It doesn't require an explanation since it is only one instruction. – jdweng Jun 14 '15 at 04:03
  • No, this won't work for XAML. XAMLs are compiled and not available as plain XML at runtime. You can't treat XAML as XML, just like you can't treat `.cs` file as text file. – har07 Jun 14 '15 at 06:19
0

It is not very clear from your question what you are trying to achieve so I will make some assumptions.

I think you want get the DataContext of the TabItem where the button was pressed, but you are binding all the buttons to the same click event handler.

If I am on the right track some of these issues could be simplified using the MVVM pattern. See here for a description to decompose each TabItem content to its own View and ViewModel.

The overall TabControl would have its own ViewModel, which would have a property for each of its TabItems (or a collection of items). Each of these would be a ViewModel and would be bound to the Content section of each tab item.

You would setup a data context map between the each ViewModel and its view, in effect telling WPF, when you see this ViewModel render that View.

When you bind each of these buttons you would be binding to an ICommand on the ViewModel, which also happens to be the Context of the current tab.

This might seem like overkill but will make things simpler in the long run.

Community
  • 1
  • 1
benPearce
  • 37,735
  • 14
  • 62
  • 96