Rotate 3D cube in WPF - wpf

I make a 3D cube in WPF with the XAML code like this:
<Viewport3D Name="viewport3D1">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camMain" Position="6 5 4" LookDirection="-6 -5 -4">
</PerspectiveCamera>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight x:Name="dirLightMain" Direction="-1,-1,-1">
</DirectionalLight>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D x:Name="meshMain"
Positions="0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 1 1 1"
TriangleIndices="2 3 1 2 1 0 7 1 3 7 5 1 6 5 7 6 4 5 6 2 0 2 0 4 2 7 3 2 6 7 0 1 5 0 5 4">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="matDiffuseMain">
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Red"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
Then is constructor of my window, I want to apply rotations around axis OX, OY, OZ which I think is supposed to be done like this:
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 2, 0), 1));
meshMain.Transform=myRotateTransform;
// etc...
It seems I don't apply transform to proper node of XAML, what it the right way to effect transform in my case?

You need to give your ModelVisual3D a name, MeshGeometry3D does not have a Transform Property where as the Model does. You also need to have access to your AxisAngleRotation3D object in order to set the Angle property.
<ModelVisual3D x:Name="MyModel">
....
Edit added more code for CodeBehind method
public partial class MainWindow : Window
{
AxisAngleRotation3D ax3d;
public MainWindow()
{
InitializeComponent();
ax3d = new AxisAngleRotation3D(new Vector3D(0, 2, 0), 1);
RotateTransform3D myRotateTransform = new RotateTransform3D(ax3d);
MyModel.Transform = myRotateTransform;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ax3d.Angle += 1 ;
}
}
Though in this case I think you would be better off implementing your Transform in the Xaml.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Viewport3D Name="viewport3D1">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camMain" Position="6 5 4" LookDirection="-6 -5 -4">
</PerspectiveCamera>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight x:Name="dirLightMain" Direction="-1,-1,-1">
</DirectionalLight>
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D x:Name="MyModel">
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D x:Name="meshMain"
Positions="0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 1 1 1 1"
TriangleIndices="2 3 1 2 1 0 7 1 3 7 5 1 6 5 7 6 4 5 6 2 0 2 0 4 2 7 3 2 6 7 0 1 5 0 5 4">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="matDiffuseMain">
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Red"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
<ModelVisual3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotate" Axis="0 2 0"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</ModelVisual3D.Transform>
</ModelVisual3D>
</Viewport3D>
<Slider Height="23" HorizontalAlignment="Left"
Margin="12,12,0,0" Name="slider1"
VerticalAlignment="Top" Width="187"
Maximum="360"
Value="{Binding ElementName=rotate, Path=Angle}" />
</Grid>
</Window>
Also with this example you can change your AxisAngleRotation3D in the CodeBehind by setting its Angle Property:
rotate.Angle +=1;

Related

Position a triangle along a slider

I want to extend a slider by a triangle pointing to a fixed position (the triangle will not be moved like the thumb).
The current code draws the triangle at position 0,0.
<Path Data="M 0 0 L 6 0 L 3 7 Z" Stroke="Black" Fill="Black"/>
The result looks like this:
In this example the slider represents a % value (the range is not necessarily 0 - 100). The triangle should be positioned at a fixed % value, which is provided via dependency property.
My question is: how do I relocate the triangle to point to that % value (not the thumbs value)?
With fixed ratio it would look like:
<Grid>
<Grid Margin="0,-10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition Width="75*"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Column="1">
<Path Data="M -3 0 L 3 0 L 0 7 Z" Stroke="Black" Fill="Black"/>
</Canvas>
</Grid>
<Slider/>
</Grid>
Notice that I changed the path to center it on the canvas.
To make the ratio dynamic you need a converter to be able to bind it to a property (a double named Percent here)
<Window.Resources>
<local:GridLengthPercentConverter x:Key="GridLengthPercentConverter" />
</Window.Resources>
...
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding
Path=Percent,
Converter={StaticResource GridLengthPercentConverter},
ConverterParameter=first"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition Width="{Binding
Path=Percent,
Converter={StaticResource GridLengthPercentConverter},
ConverterParameter=other"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Column="1">
<Path Data="M -3 0 L 3 0 L 0 7 Z" Stroke="Black" Fill="Black"/>
</Canvas>
</Grid>
<Slider/>
</Grid>
Here's how the converter looks like:
public class GridLengthPercentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(parameter.ToString() == "first")
return new GridLength((double)value, GridUnitType.Star)
return new GridLength(100 - (double)value, GridUnitType.Star)
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}

Why ComboBox item shrinks in the DropDownBorder after it is selected?

I have a ComboBox for which I bound ItemsSource to a enum collection and SelectedItem to a DependencyProperty of the same enum type. So far no problem.
Now I want to display a drawing (associated with each value of the enum collection) instead of the text.
My idea is to use a Converter to translate the value to drawing (and viceversa), using the resource Tag.
in MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApp1"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
x:Class="WpfApp1.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="200">
<Window.Resources>
<ObjectDataProvider x:Key="Letters" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:Letters"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:LetterConverter x:Key="LetterConverter"/>
</Window.Resources>
<Grid>
<ComboBox x:Name="Letter" Grid.Row="0" Width="48" Height="32" ItemsSource="{Binding Source={StaticResource Letters}}" SelectedItem="{Binding Path=SelectedLetter}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Viewbox Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border>
<ContentPresenter Content="{Binding Converter={StaticResource LetterConverter}}"/>
</Border>
</Viewbox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Window>
in MainWindow.cs
using System;
using System.Windows;
using System.Windows.Data;
namespace WpfApp1
{
/// <summary>
/// Logica di interazione per MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region SelectedLetter property
public Letters SelectedLetter
{
get { return (Letters)GetValue(SelectedLetterProperty); }
set { SetValue(SelectedLetterProperty, value); }
}
public static readonly DependencyProperty SelectedLetterProperty =
DependencyProperty.Register("SelectedLetter", typeof(Letters), typeof(MainWindow), new PropertyMetadata(Letters.E, new PropertyChangedCallback(LetterChanged)));
private static void LetterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MainWindow instance = d as MainWindow;
MessageBox.Show(e.NewValue.ToString());
}
#endregion
public MainWindow()
{
InitializeComponent();
}
}
public enum Letters
{
A, B, C, D, E
}
[ValueConversion(typeof(Letters), typeof(FrameworkElement))]
public class LetterConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch ((Letters)value)
{
case Letters.A:
return (FrameworkElement)Application.Current.Resources["A"];
case Letters.B:
return (FrameworkElement)Application.Current.Resources["B"];
case Letters.C:
return (FrameworkElement)Application.Current.Resources["C"];
case Letters.D:
return (FrameworkElement)Application.Current.Resources["D"];
case Letters.E:
return (FrameworkElement)Application.Current.Resources["E"];
default:
throw new ArgumentOutOfRangeException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (((FrameworkElement)value).Tag.ToString().Equals("A"))
return Letters.A;
if (((FrameworkElement)value).Tag.ToString().Equals("B"))
return Letters.B;
if (((FrameworkElement)value).Tag.ToString().Equals("C"))
return Letters.C;
if (((FrameworkElement)value).Tag.ToString().Equals("D"))
return Letters.D;
if (((FrameworkElement)value).Tag.ToString().Equals("E"))
return Letters.E;
throw new ArgumentOutOfRangeException();
}
}
}
in App.xaml
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Canvas x:Key="A" Width="24" Height="24" Tag="A">
<Path Width="24" Height="24" Data="M11,7H13A2,2 0 0,1 15,9V17H13V13H11V17H9V9A2,2 0 0,1 11,7M11,9V11H13V9H11M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="B" Width="24" Height="24" Tag="B">
<Path Width="24" Height="24" Data="M15,10.5C15,11.3 14.3,12 13.5,12C14.3,12 15,12.7 15,13.5V15A2,2 0 0,1 13,17H9V7H13A2,2 0 0,1 15,9V10.5M13,15V13H11V15H13M13,11V9H11V11H13M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="C" Width="24" Height="24" Tag="C">
<Path Width="24" Height="24" Data="M11,7H13A2,2 0 0,1 15,9V10H13V9H11V15H13V14H15V15A2,2 0 0,1 13,17H11A2,2 0 0,1 9,15V9A2,2 0 0,1 11,7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="D" Width="24" Height="24" Tag="D">
<Path Width="24" Height="24" Data="M9,7H13A2,2 0 0,1 15,9V15A2,2 0 0,1 13,17H9V7M11,9V15H13V9H11M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="E" Width="24" Height="24" Tag="E">
<Path Width="24" Height="24" Data="M9,7H15V9H11V11H15V13H11V15H15V17H9V7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
</Application.Resources>
</Application>
At this point, once an element is selected from the drop-list, it becomes smaller and is no longer visible.
Any suggestions?
Set the x:Shared attribute of your resources to false:
<Canvas x:Key="A" Width="24" Height="24" Tag="A" x:Shared="False">
<Path Width="24" Height="24" Data="M11,7H13A2,2 0 0,1 15,9V17H13V13H11V17H9V9A2,2 0 0,1 11,7M11,9V11H13V9H11M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="B" Width="24" Height="24" Tag="B" x:Shared="False">
<Path Width="24" Height="24" Data="M15,10.5C15,11.3 14.3,12 13.5,12C14.3,12 15,12.7 15,13.5V15A2,2 0 0,1 13,17H9V7H13A2,2 0 0,1 15,9V10.5M13,15V13H11V15H13M13,11V9H11V11H13M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="C" Width="24" Height="24" Tag="C" x:Shared="False">
<Path Width="24" Height="24" Data="M11,7H13A2,2 0 0,1 15,9V10H13V9H11V15H13V14H15V15A2,2 0 0,1 13,17H11A2,2 0 0,1 9,15V9A2,2 0 0,1 11,7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="D" Width="24" Height="24" Tag="D" x:Shared="False">
<Path Width="24" Height="24" Data="M9,7H13A2,2 0 0,1 15,9V15A2,2 0 0,1 13,17H9V7M11,9V15H13V9H11M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
<Canvas x:Key="E" Width="24" Height="24" Tag="E" x:Shared="False">
<Path Width="24" Height="24" Data="M9,7H15V9H11V11H15V13H11V15H15V17H9V7M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" Fill="Black"/>
</Canvas>
If you don't, the same Canvas element is reused and a visual element can only appear once in the visual tree.

How to change vector color in a resource from code behind

How would I change the vector color from the code behind? Code behind in this example doesn't work.
From the Resource Dictionary..
<VisualBrush x:Key="Alarm-Light">
<VisualBrush.Visual>
<Canvas>
<Path Data="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22M12,7L7,12H10V16H14V12H17L12,7Z" Fill="#424242" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
From the Xaml..
<TextBlock x:Name="TextConnect" Width="20">
<Rectangle x:Name="AlarmLight" Fill="{StaticResource Alarm-Light}" Height="16" Width="16" />
Code Behind...
private void Connection_Check()
{
var brush = LocalSystem.Connected ? new SolidColorBrush(Colors.GreenYellow) : new SolidColorBrush(Colors.DimGray);
AlarmLight.Fill = brush;
}
This works:
<VisualBrush x:Key="Alarm-Light">
<VisualBrush.Visual>
<Canvas>
<Path Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=AlarmFill}" Data="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22M12,7L7,12H10V16H14V12H17L12,7Z" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
With this code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AlarmFill = new SolidColorBrush(Colors.Blue);
}
/// <summary>
/// Gets or Sets AlarmFill Dependency Property
/// </summary>
public Brush AlarmFill
{
get { return (Brush)GetValue(AlarmFillProperty); }
set { SetValue(AlarmFillProperty, value); }
}
public static readonly DependencyProperty AlarmFillProperty =
DependencyProperty.Register("AlarmFill", typeof(Brush), typeof(MainWindow), new PropertyMetadata(null));
}
Or this one:
<VisualBrush x:Key="Alarm-Light">
<VisualBrush.Visual>
<Canvas>
<Path Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.AlarmFill}" Data="M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22M12,7L7,12H10V16H14V12H17L12,7Z" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
With this code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
AlarmFill = new SolidColorBrush(Colors.Blue);
}
/// <summary>
/// Gets or Sets AlarmFill Dependency Property
/// </summary>
public Brush AlarmFill
{
get { return (Brush)GetValue(AlarmFillProperty); }
set { SetValue(AlarmFillProperty, value); }
}
public static readonly DependencyProperty AlarmFillProperty =
DependencyProperty.Register("AlarmFill", typeof(Brush), typeof(MainWindow), new PropertyMetadata(null));
}

bind the property to the resource in ResouceDictionary

My application has some menu buttons, and the button shows the current selection, for example, if user selects "Red", the button image is "Red pen". I prepare XAML files for the button image, like this.
<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SmartScreen">
<DrawingBrush x:Key="sample_test" Stretch="Uniform">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 87.7748,67.8528L 87.7748,54.9208C 87.7748,52.9101 86.1441,51.2781 84.1375,51.2781L 61.3575,51.2781L 61.3575,24.4635L 63.1001,24.4635C 64.7948,24.4635 66.1788,23.0808 66.1788,21.3861L 66.1788,8.06213C 66.1788,6.36613 64.7948,4.9888 63.1001,4.9888L 49.7748,4.9888C 48.0801,4.9888 46.6988,6.36613 46.6988,8.06213L 46.6988,21.3861C 46.6988,23.0808 48.0801,24.4635 49.7748,24.4635L 51.5095,24.4635L 51.5095,51.2781L 28.7348,51.2781C 27.2241,51.2781 25.9228,52.2061 25.3735,53.5115C 26.0281,53.4501 26.6948,53.4168 27.3601,53.4168C 37.6975,53.4168 46.2041,61.3808 47.0895,71.4915L 84.1375,71.4915C 86.1441,71.4915 87.7748,69.8595 87.7748,67.8528 Z "/>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 84.138,84.7019C 86.1447,84.7019 87.7753,83.0739 87.7753,81.0672L 87.7753,79.0565C 87.7753,77.0365 86.1447,75.4139 84.138,75.4139L 47.046,75.4139C 46.666,78.8512 45.402,82.0219 43.4873,84.7019L 84.138,84.7019 Z "/>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 27.3607,85.9973C 20.302,85.9973 14.5847,80.2747 14.5847,73.2253C 14.5847,66.1707 20.302,60.4467 27.3607,60.4467C 34.4193,60.4467 40.134,66.1707 40.134,73.2253C 40.134,80.2747 34.4193,85.9973 27.3607,85.9973 Z M 27.3607,56.9733C 18.386,56.9733 11.114,64.2467 11.114,73.2253C 11.114,82.1933 18.386,89.4693 27.3607,89.4693C 36.3313,89.4693 43.6113,82.1933 43.6113,73.2253C 43.6113,64.2467 36.3313,56.9733 27.3607,56.9733 Z "/>
<GeometryDrawing Brush="{Binding Path=SampleColor}" Geometry="F1 M 35.8893,71.2825L 29.3013,71.2825L 29.3013,63.6785C 29.3013,62.6105 28.4333,61.7465 27.3613,61.7465C 26.288,61.7465 25.4253,62.6105 25.4253,63.6785L 25.4253,72.2132C 25.4253,72.3905 25.4507,72.5559 25.4933,72.7199C 25.4507,72.8785 25.4253,73.0425 25.4253,73.2252C 25.4253,74.2932 26.288,75.1572 27.3613,75.1572L 35.8893,75.1572C 36.964,75.1572 37.8293,74.2932 37.8293,73.2252C 37.8293,72.1532 36.964,71.2825 35.8893,71.2825 Z "/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</ResourceDictionary>
Put this file (named 'sample_test.xaml') to the ResourceDictionary of Applicaton.Resources.
<Application x:Class="SmartScreen.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="sample_test.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MainWindow.xaml is following,
<Window x:Class="SmartScreen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:Test">
<Grid Loaded="Grid_Loaded">
<Label Name="label1" Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center"
Background="{DynamicResource sample_test}"
/>
<Label Name="label2" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="100,0">
<Label.Background>
<DrawingBrush Stretch="Uniform">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 87.7748,67.8528L 87.7748,54.9208C 87.7748,52.9101 86.1441,51.2781 84.1375,51.2781L 61.3575,51.2781L 61.3575,24.4635L 63.1001,24.4635C 64.7948,24.4635 66.1788,23.0808 66.1788,21.3861L 66.1788,8.06213C 66.1788,6.36613 64.7948,4.9888 63.1001,4.9888L 49.7748,4.9888C 48.0801,4.9888 46.6988,6.36613 46.6988,8.06213L 46.6988,21.3861C 46.6988,23.0808 48.0801,24.4635 49.7748,24.4635L 51.5095,24.4635L 51.5095,51.2781L 28.7348,51.2781C 27.2241,51.2781 25.9228,52.2061 25.3735,53.5115C 26.0281,53.4501 26.6948,53.4168 27.3601,53.4168C 37.6975,53.4168 46.2041,61.3808 47.0895,71.4915L 84.1375,71.4915C 86.1441,71.4915 87.7748,69.8595 87.7748,67.8528 Z "/>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 84.138,84.7019C 86.1447,84.7019 87.7753,83.0739 87.7753,81.0672L 87.7753,79.0565C 87.7753,77.0365 86.1447,75.4139 84.138,75.4139L 47.046,75.4139C 46.666,78.8512 45.402,82.0219 43.4873,84.7019L 84.138,84.7019 Z "/>
<GeometryDrawing Brush="#FF000000" Geometry="F1 M 27.3607,85.9973C 20.302,85.9973 14.5847,80.2747 14.5847,73.2253C 14.5847,66.1707 20.302,60.4467 27.3607,60.4467C 34.4193,60.4467 40.134,66.1707 40.134,73.2253C 40.134,80.2747 34.4193,85.9973 27.3607,85.9973 Z M 27.3607,56.9733C 18.386,56.9733 11.114,64.2467 11.114,73.2253C 11.114,82.1933 18.386,89.4693 27.3607,89.4693C 36.3313,89.4693 43.6113,82.1933 43.6113,73.2253C 43.6113,64.2467 36.3313,56.9733 27.3607,56.9733 Z "/>
<GeometryDrawing Brush="{Binding SampleColor}" Geometry="F1 M 35.8893,71.2825L 29.3013,71.2825L 29.3013,63.6785C 29.3013,62.6105 28.4333,61.7465 27.3613,61.7465C 26.288,61.7465 25.4253,62.6105 25.4253,63.6785L 25.4253,72.2132C 25.4253,72.3905 25.4507,72.5559 25.4933,72.7199C 25.4507,72.8785 25.4253,73.0425 25.4253,73.2252C 25.4253,74.2932 26.288,75.1572 27.3613,75.1572L 35.8893,75.1572C 36.964,75.1572 37.8293,74.2932 37.8293,73.2252C 37.8293,72.1532 36.964,71.2825 35.8893,71.2825 Z "/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Label.Background>
</Label>
</Grid>
</Window>
Finnally, the view model of MainWindow should has the property named "SampleColor" like this;
namespace Sample
{
...
public class MainWindowViewModel
{
public Brush SampleColor
{
get
{
return Brushes.Red;
}
}
}
}
Result, the label named "label2" shows the red parts, but "label1" doesn't.
I don't know how to tell the DataContext to the resource in the ResourceDictionary.
This is very simular, but DrawinBrush has no DataContext.

WPF Drag & Drop: How to literally drag an element?

Say I have a ListBox with some items and say I implement drag and drop functionality for that list. If I want to drag an item from that list box, how can I actually move the dragged item?
I want to achieve the effect of having the list box item under my mouse cursor and to be able to move with it as I drag it on the window. By following this example, all I get is a cursor change based on the DragDropEffects enum choice.
This is typically done using an adorner. See here for an example.
Resize.Xaml:
<UserControl x:Class="ERDesign.Resize"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ERDesign="clr-namespace:ERDesign"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="150" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<UserControl.Resources>
<ControlTemplate x:Key="TemplateResize" TargetType="{x:Type Control}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<Rectangle Margin="-6 -6 -6 -6" Stroke="#FF555555" StrokeThickness="1" StrokeDashArray="4.0 4.0" SnapsToDevicePixels="True"></Rectangle>
<ERDesign:ResizeHandle HorizontalAlignment="Left" VerticalAlignment="Top" Margin="-10 -10 0 0" Cursor="SizeNWSE" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0 -10 0 0" Cursor="SizeNS" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0 -10 -10 0" Cursor="SizeNESW" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Left" VerticalAlignment="Center" Margin="-10 0 0 0" Cursor="SizeWE" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0 0 -10 0" Cursor="SizeWE" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="-10 0 0 -10" Cursor="SizeNESW" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0 0 0 -10" Cursor="SizeNS" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
<ERDesign:ResizeHandle HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0 0 -10 -10" Cursor="SizeNWSE" SnapsToDevicePixels="True"></ERDesign:ResizeHandle>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Control HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Template="{StaticResource TemplateResize}" SnapsToDevicePixels="True"></Control>
</UserControl>
ResizeHandle.Xaml
<UserControl x:Class="ERDesign.ResizeHandle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="9" d:DesignWidth="9" Width="9" Height="9">
<UserControl.Resources>
<ControlTemplate x:Key="TemplateResizeHandle" TargetType="{x:Type Thumb}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<Ellipse Stroke="#FF2F592F" Stretch="Fill">
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.3,0.3">
<GradientStop Color="#FFF2FCF2" Offset="0"></GradientStop>
<GradientStop Color="#FF4ECB4E" Offset="1"></GradientStop>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</UserControl.Resources>
<Thumb HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Template="{StaticResource TemplateResizeHandle}" SnapsToDevicePixels="True" DragDelta="Thumb_DragDelta"></Thumb>
</UserControl>
ResizeHandle.Xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace ERDesign
{
public partial class ResizeHandle : UserControl
{
public ResizeHandle()
{
InitializeComponent();
}
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
ResizeHandle resizehandle = (sender as Thumb).Parent as ResizeHandle;
Resize resize = (resizehandle.DataContext as Control).Parent as Resize;
UserControl userctrl = (resize.DataContext as ContentControl).Parent as UserControl;
if (userctrl == null)
{
}
else
{
double X;
double Y;
switch (this.HorizontalAlignment)
{
case HorizontalAlignment.Left:
X = Math.Min(e.HorizontalChange, userctrl.ActualWidth - userctrl.MinWidth);
Canvas.SetLeft(userctrl, Canvas.GetLeft(userctrl) + X);
userctrl.Width = userctrl.Width - X;
break;
case HorizontalAlignment.Right:
X = Math.Min(-e.HorizontalChange, userctrl.ActualWidth - userctrl.MinWidth);
userctrl.Width = userctrl.Width - X;
break;
default:
break;
}
switch (this.VerticalAlignment)
{
case VerticalAlignment.Top:
Y = Math.Min(e.VerticalChange, userctrl.ActualHeight - userctrl.MinHeight);
Canvas.SetTop(userctrl, Canvas.GetTop(userctrl) + Y);
userctrl.Height = userctrl.Height - Y;
break;
case VerticalAlignment.Bottom:
Y = Math.Min(-e.VerticalChange, userctrl.ActualHeight - userctrl.MinHeight);
userctrl.Height = userctrl.Height - Y;
break;
default:
break;
}
}
}
}
}

Resources