Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Framework (managed code) (https://www.delphipraxis.net/79-net-framework-managed-code/)
-   -   C# [WPF] "Auflösung" von Controls in ItemsControl (https://www.delphipraxis.net/190676-%5Bwpf%5D-aufloesung-von-controls-itemscontrol.html)

Neutral General 25. Okt 2016 10:04

[WPF] "Auflösung" von Controls in ItemsControl
 
Hallo,

Ich habe gerade ein total blödes Problem. Als Basis dient dieses CustomControl:
(Ein rotes Grid mit einem gelben Rechteck in der Mitte).

XAML:
Code:
<ResourceDictionary>
    <ControlTemplate x:Key="TESTCONTROL_TEMPLATE" TargetType="{x:Type local:TestControl}">
        <Grid Background="Red">
            <Rectangle Width="50" Height="50" VerticalAlignment="Center" HorizontalAlignment="Center" Fill="Yellow"/>
        </Grid>
    </ControlTemplate>

    <Style TargetType="{x:Type local:TestControl}">
        <Setter Property="Template" Value="{StaticResource TESTCONTROL_TEMPLATE}"/>
    </Style>
</ResourceDictionary>

Code:
Code:
public class TestControl : Control
{

}
Nun folgende beiden Anwendungsbeispiele:

Beispiel 1:
XAML:
Code:
<Window>
  <Canvas x:Name="TestCanvas" MouseLeftButtonDown="TestCanvas_MouseLeftButtonDown"/>
</Window>
Code:
Code:
public partial class MyWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    TestControl control = new TestControl();
    control.Width = 100;
    control.Height = 100;

    TestCanvas.Children.Add(control);
  }
}
Beispiel 2:
XAML:
Code:
<Window>
  <ItemsControl x:Name="TestItemsCtrl">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <Canvas MouseLeftButtonDown="TestCanvas_MouseLeftButtonDown"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
  </ItemsControl>
</Window>
Code:
Code:
public partial class MyWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    TestControl control = new TestControl();
    List<TestControl> controlList = new List<TestControl>();
    controlList.Add(control);

    TestItemsCtrl.ItemsSource = controlList;
  }
}
Mein Problem zeigt sich im MouseLeftButtonClick des jeweiligen Canvas:
Code:
private void TestCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  Title = e.Source.GetType().Name;
}
In Beispiel 1 enthält Source das "TestControl" - so soll es sein.
In Beispiel 2 enthält Source je nachdem wohin ich auf das TestControl geklickt habe entweder das Grid oder das Rectangle,
also nur die Einzelbestandteile meines TestControls statt dem ganzen TestControl.

Warum ist das so und was kann ich dagegen machen? Ich will genauso wie wenn ich das Control einfach im Code zum Canvas hinzufüge das TestControl als "Ganzes" anklicken und nicht die Einzelbestandteile :(

aMuTeX 25. Okt 2016 10:50

AW: [WPF] "Auflösung" von Controls in ItemsControl
 
Hallo

Warum das so ist habe ich auch nie verstanden. "e.Source" und "e.OriginalSource" sind nicht gleich, obwohl der VisualTree sonst eigentlich gleich ist.

Das gewünschte Ergebnis kann aber so erreicht werden:
Code:
private void TestCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Title = UIHelper.FindVisualParent<TestControl>(e.OriginalSource as DependencyObject).GetType().Name;
}
Code:
public static class UIHelper
{
    /// <summary>
    /// Finds a parent of a given item on the visual tree.
    /// </summary>
    /// <typeparam name="T">The type of the queried item.</typeparam>
    /// <param name="child">A direct or indirect child of the queried item.</param>
    /// <returns>The first parent item that matches the submitted type parameter.
    /// If not matching item can be found, a null reference is being returned.</returns>
    public static T FindVisualParent<T>(DependencyObject child)
      where T : DependencyObject
    {
        // get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);


        // we’ve reached the end of the tree
        if (parentObject == null) return null;

        // check if the parent matches the type we’re looking for
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            // use recursion to proceed with next level
            return FindVisualParent<T>(parentObject);
        }
    }
}
Hoffe das hilft.
Gruss
Stefan

Neutral General 25. Okt 2016 11:53

AW: [WPF] "Auflösung" von Controls in ItemsControl
 
Hi aMuTeX,

Danke schonmal für deine Antwort. Den VisualTree hochklettern hatte ich auch schon als Alternative im Kopf gehabt, aber ich finde das ist irgendwie keine besonders schöne Lösung :|
Woher kommt das denn? Wie kommt dieser Unterschied überhaupt zustande? Ich wüsste gar nicht was ich machen müsste um dieses ungewollte Verhalten bewusst herbeizuführen.

aMuTeX 25. Okt 2016 15:26

AW: [WPF] "Auflösung" von Controls in ItemsControl
 
Zitat:

Zitat von Neutral General (Beitrag 1351976)
Woher kommt das denn? Wie kommt dieser Unterschied überhaupt zustande?

Das wüsste ich auch gerne...


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz