views:

738

answers:

2

I hoped the answer to my previous question whould help me with this one, but it didn't. the initial situation is pretty much the same:

<TreeView ItemsSource="{Binding Groups}" Name="tvGroups" AllowDrop="True">
          <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Participants}">
                          <StackPanel Orientation="Horizontal" Drop="tvDrop" Tag="{Binding .}">
                               <TextBlock Text="{Binding Name}" />
                               <Button Tag="{Binding .}" Click="Button_Click_2">
                                    <Image Source="Resources/cross.png" />
                                </Button>
                          </StackPanel>
                          <HierarchicalDataTemplate.ItemTemplate>
                              <DataTemplate>
                                  <StackPanel Orientation="Horizontal" >
                                       <TextBlock Text="{Binding Alias}" />
                                       <Button Tag="{Binding .}" Name="btnDeleteParticipants" Click="btnParticipants_Click" >
                                            <Image Source="Resources/cross.png" />
                                       </Button>
                                  </StackPanel>
                              </DataTemplate>
                          </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
          </TreeView.ItemTemplate>
</TreeView>


 private void btnParticipants_Click(object sender, RoutedEventArgs e)//Probanten aus Gruppe entfernen
        {
            Participant p = ((sender as Button).Tag as Participant);
            if (p == null) return;
            //TODO: Raus bekommen in welcher Gruppe ich löschen will

        }

I want to remove Participant p from a Group by clicking the button(btnDeleteParticipants). I tried something like this one:

Control c = sender as Control;
while (!(c is TreeViewItem))
     c = (c.Parent) as Control;

But this didn't work(don't aks why, i'm not sure). I could find the Group by checking if it contains the Participant(bound to btnDeleteParticipants.Tag), but this would disallow participants to be in more than 1 group. So, any ideas how to get the right Group?

Edit:

Groups = new ObservableCollection<Group>();
Participants = new ObservableCollection<Participant>();
+1  A: 

Are Groups and Participants ObservableCollection objects?

Try using this:

static TObject FindVisualParent<TObject>(UIElement child) where TObject : UIElement
{
  if (child == null)
  {
    return null;
  }

  UIElement parent = VisualTreeHelper.GetParent(child) as UIElement;

  while (parent != null)
  {
    TObject found = parent as TObject;
    if (found != null)
    {
      return found;
    }
    else
    {
      parent = VisualTreeHelper.GetParent(parent) as UIElement;
    }
  }

  return null;
}

Also, try using the DataContext to get the participant and set the Tag to the TemplatedParent.

<Button Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}" />

Then on click

private void btnParticipants_Click(object sender, RoutedEventArgs e)
{
  var button = sender as Button;
  var p = button.DataContext as Participant;
  if (p == null) return;

  var t= FindVisualParent<TreeViewItem>(button); // get the Participants TreeViewItem
  if (t == null) return;
  var groupTreeItem = FindVisualParent<TreeViewItem>(t);  // get the groups TreeViewItem
  if (groupTreeItem == null) return;
  var group = groupTreeItem.DataContext as Group;
  group.Participants.Remove(p);
}
bendewey
sry, i don't see how to use this methode. whats up with `this` before the ParamterType (**this** TreeViewItem item)? I don't have a TreeViewItem for use as a parameter.
Marcel Benthin
That's a so-called extension method. You can call it on a TReeViewItem as if it were a method declared on TVI.
Joey
your XAML doesn't work. I need to add a Path.(and whats up with this asp namespace?)
Marcel Benthin
I removed the asp part my bad. They Path shouldn't be required.
bendewey
sry. this time my bad.(I hate when VS needs a build for updating syntaxhighlighting)
Marcel Benthin
var t = button.Tag as TreeViewItem;//returns allways nullbutton.Tag.getType() returns System.Windows.Controls.ContentPresenter
Marcel Benthin
oh, I wasn't expecting that, I think its because you are using the HierarchicalDataTemplate. I'll have to load this up and take a look. The idea is to get the Tag property bound to an instance of the TreeViewItem.
bendewey
I updated my post and got rid of the Extension method. Its been replaced by a static FindVisualParent method. sorry to spin you around, I don't have the right software with me today.
bendewey
Why does the collection have to be observable?
ClearsTheScreen
A: 

Although this is not a direct answer, you might find this article by Josh Smith interesting.

mostlytech