Note that there are some explanatory texts on larger screens.

plurals
  1. POWPF: how to find an element in a datatemplate from an itemscontrol
    text
    copied!<p>I have the following problem: the application is using the custom itemscontrol called ToolBox. The elements of a toolbox are called toolboxitems and are custom contentcontrol. Now, the toolbox stores a number of images that are retrieved from a database and displayed. For that I use a datatemplate inside the toolbox control. However, when I try to drag and drop the elements, I don't get the image object but the database component. I thought that I should then traverse the structure to find the Image element. here's the code:</p> <p>Toolbox:</p> <pre><code>public class Toolbox : ItemsControl { private Size defaultItemSize = new Size(65, 65); public Size DefaultItemSize { get { return this.defaultItemSize; } set { this.defaultItemSize = value; } } protected override DependencyObject GetContainerForItemOverride() { return new ToolboxItem(); } protected override bool IsItemItsOwnContainerOverride(object item) { return (item is ToolboxItem); } } </code></pre> <p>ToolBoxItem:</p> <pre><code>public class ToolboxItem : ContentControl { private Point? dragStartPoint = null; static ToolboxItem() { FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(ToolboxItem), new FrameworkPropertyMetadata(typeof(ToolboxItem))); } protected override void OnPreviewMouseDown(MouseButtonEventArgs e) { base.OnPreviewMouseDown(e); this.dragStartPoint = new Point?(e.GetPosition(this)); } public String url { get; private set; } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.LeftButton != MouseButtonState.Pressed) { this.dragStartPoint = null; } if (this.dragStartPoint.HasValue) { Point position = e.GetPosition(this); if ((SystemParameters.MinimumHorizontalDragDistance &lt;= Math.Abs((double)(position.X - this.dragStartPoint.Value.X))) || (SystemParameters.MinimumVerticalDragDistance &lt;= Math.Abs((double)(position.Y - this.dragStartPoint.Value.Y)))) { string xamlString = XamlWriter.Save(this.Content); MessageBoxResult result = MessageBox.Show(xamlString); DataObject dataObject = new DataObject("DESIGNER_ITEM", xamlString); if (dataObject != null) { DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Copy); } } e.Handled = true; } } private childItem FindVisualChild&lt;childItem&gt;(DependencyObject obj) where childItem : DependencyObject { for (int i = 0; i &lt; VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null &amp;&amp; child is childItem) return (childItem)child; else { childItem childOfChild = FindVisualChild&lt;childItem&gt;(child); if (childOfChild != null) return childOfChild; } } return null; } } </code></pre> <p>here is the xaml file for ToolBox and toolbox item:</p> <pre><code> &lt;Style TargetType="{x:Type s:ToolboxItem}"&gt; &lt;Setter Property="Control.Padding" Value="5" /&gt; &lt;Setter Property="ContentControl.HorizontalContentAlignment" Value="Stretch" /&gt; &lt;Setter Property="ContentControl.VerticalContentAlignment" Value="Stretch" /&gt; &lt;Setter Property="ToolTip" Value="{Binding ToolTip}" /&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type s:ToolboxItem}"&gt; &lt;Grid&gt; &lt;Rectangle Name="Border" StrokeThickness="1" StrokeDashArray="2" Fill="Transparent" SnapsToDevicePixels="true" /&gt; &lt;ContentPresenter Content="{TemplateBinding ContentControl.Content}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" ContentTemplate="{TemplateBinding ContentTemplate}"/&gt; &lt;/Grid&gt; &lt;ControlTemplate.Triggers&gt; &lt;Trigger Property="IsMouseOver" Value="true"&gt; &lt;Setter TargetName="Border" Property="Stroke" Value="Gray" /&gt; &lt;/Trigger&gt; &lt;/ControlTemplate.Triggers&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; &lt;Style TargetType="{x:Type s:Toolbox}"&gt; &lt;Setter Property="SnapsToDevicePixels" Value="true" /&gt; &lt;Setter Property="Focusable" Value="False" /&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate&gt; &lt;Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True"&gt; &lt;ScrollViewer VerticalScrollBarVisibility="Auto"&gt; &lt;ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /&gt; &lt;/ScrollViewer&gt; &lt;/Border&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;Setter Property="ItemsPanel"&gt; &lt;Setter.Value&gt; &lt;ItemsPanelTemplate&gt; &lt;WrapPanel Margin="0,5,0,5" ItemHeight="{Binding Path=DefaultItemSize.Height, RelativeSource={RelativeSource AncestorType=s:Toolbox}}" ItemWidth="{Binding Path=DefaultItemSize.Width, RelativeSource={RelativeSource AncestorType=s:Toolbox}}" /&gt; &lt;/ItemsPanelTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; &lt;/ResourceDictionary&gt; </code></pre> <p>Example usage:</p> <pre><code>&lt;Toolbox x:Name="NewLibrary" DefaultItemSize="55,55" ItemsSource="{Binding}" &gt; &lt;ItemsControl.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;StackPanel&gt; &lt;Image Source="{Binding Path=url}" /&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;/ItemsControl.ItemTemplate&gt; &lt;/Toolbox&gt; </code></pre> <p>The object that I get is a database object. When using a static resource I get the Image object. How to retrieve this Image object from a datatemplate? I though that I could use this tutorial: <a href="http://msdn.microsoft.com/en-us/library/bb613579.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/bb613579.aspx</a> But it does not seem to solve the problem. Could anyone suggest a solution? Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload