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.
Related
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;
}
}
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));
}
I have one class ChromeWindow which is derived from Window class. It has one custom dependency property
public class ChromeWindow : System.Windows.Window
{
public static readonly DependencyProperty TitleBarHeightProperty = DependencyProperty.Register("TitleBarHeight", typeof(int), typeof(ChromeWindow), new FrameworkPropertyMetadata(TitleBarHeightChangedCallback));
public int TitleBarHeight
{
get
{
return (int)GetValue(TitleBarHeightProperty);
}
set
{
SetValue(TitleBarHeightProperty, value);
}
}
private static void TitleBarHeightChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
}
And ChromeWindow has its own control template as below.
<ControlTemplate x:Key="ChromeWindowTemplate" TargetType="local:ChromeWindow">
<Grid>
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
<StackPanel x:Name="PART_TitleBar"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="Transparent"
Height="?">
<StackPanel HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<Button x:Name="PART_MinimizeButton"
Width="34"
Height="26"
Style="{DynamicResource SystemButton}"
ToolTip="Minimize">
<Path Width="8"
Height="8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1M0,6L0,9 9,9 9,6 0,6z"
Fill="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Button}}" />
</Button>
<Button x:Name="PART_MaximizeButton"
Width="34"
Height="26"
Style="{DynamicResource SystemButton}"
ToolTip="Maximize">
<Path x:Name="PART_MaximizeButtonPath"
Width="10"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,8 1,3z"
Fill="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Button}}" />
</Button>
<Button x:Name="PART_CloseButton"
Width="34"
Height="26"
Style="{DynamicResource SystemButton}"
ToolTip="Close">
<Path Width="10"
Height="8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1M0,0L2,0 5,3 8,0 10,0 6,4 10,8 8,8 5,5 2,8 0,8 4,4 0,0z"
Fill="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Button}}" />
</Button>
</StackPanel>
</StackPanel>
<ResizeGrip x:Name="PART_ResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Cursor="SizeNWSE"
Visibility="Hidden" />
</Grid>
</ControlTemplate>
How can I bind PART_Titlebar Height to custom dependency property called "TitleBarHeight" such that
If TitleBarHeight value is not specified, title bar height should
be calculated according to its child contents ?
If TitleBarHeight value is specified, use that value.
Thanks in advance.
The default value of the Height property is double.NaN, which indicates that there is no explicitly set height.
So you should change the type of your dependency property to double and set double.NaN as its default value:
public static readonly DependencyProperty TitleBarHeightProperty =
DependencyProperty.Register(
nameof(TitleBarHeight), typeof(double), typeof(ChromeWindow),
new FrameworkPropertyMetadata(double.NaN));
public double TitleBarHeight
{
get { return (double)GetValue(TitleBarHeightProperty); }
set { SetValue(TitleBarHeightProperty, value); }
}
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;
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;
}
}
}
}
}