所以在我的应用程序中,我必须使用类对象类型, Circles 和 Rectangles 。两者都使用ListBox绘制。矩形为绿色,圆圈为黄色。
您可能会问为什么我使用列表框来显示它们。这里的好处是免费赠送用户可以在窗口中点击时选择项目。
我需要帮助的问题,它们都与点击/选择相同的主题有关。
更新时间:2016年1月7日
问题(左)|期望的目标(右)
就代码而言,它相当短,并且我将它简化为较小的文件。
MainWindow.xaml
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplication1
{
public class MainWindowViewModel
{
private ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();
public ObservableCollection<ItemViewModel> Items { get { return items; } }
public MainWindowViewModel()
{
// Populate the view model with some example data.
items.Add(new RectangleViewModel(250, 200));
items.Add(new RectangleViewModel(320, 370));
items.Add(new RectangleViewModel(100, 50));
items.Add(new RectangleViewModel(350, 25));
items.Add(new RectangleViewModel(70, 270));
items.Add(new CircleViewModel(20, 20));
items.Add(new CircleViewModel(300, 270));
items.Add(new CircleViewModel(350, 100));
items.Add(new CircleViewModel(50, 315));
items.Add(new CircleViewModel(100, 170));
}
}
public class ItemViewModel
{
// position coordinates
public double X { get; set; }
public double Y { get; set; }
}
public class CircleViewModel : ItemViewModel
{
// Constructors
public CircleViewModel(double x, double y)
{
this.X = x;
this.Y = y;
}
}
public class RectangleViewModel : ItemViewModel
{
// Constructors
public RectangleViewModel(double x, double y)
{
this.X = x;
this.Y = y;
}
}
}
MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DragShapes
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
UIElement source = null;
private void shape_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("MouseDown--Pressed");
source = (UIElement)sender;
Mouse.Capture(source);
captured = true;
x_shape = Canvas.GetLeft(source);
x_canvas = e.GetPosition(LayoutRoot).X;
y_shape = Canvas.GetTop(source);
y_canvas = e.GetPosition(LayoutRoot).Y;
}
private void shape_MouseMove(object sender, MouseEventArgs e)
{
if (captured)
{
Console.WriteLine("MouseMove--Pressed");
double x = e.GetPosition(LayoutRoot).X;
double y = e.GetPosition(LayoutRoot).Y;
x_shape += x - x_canvas;
Canvas.SetLeft(source, x_shape);
x_canvas = x;
y_shape += y - y_canvas;
Canvas.SetTop(source, y_shape);
y_canvas = y;
}
}
private void
shape_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("MouseUp--Pressed");
Mouse.Capture(null);
captured = false;
}
}
}
更新 - 更接近 - 尝试#2
现在我可以在画布中拖动和移动项目,点击的hitTest是正确的。但是出于某些原因,当我尝试在底部蓝色画布中移动形状时,它们不会移动,而它们会在顶部移动。试试吧......
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DragShapes
{
public class MainWindowViewModel
{
private ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();
public ObservableCollection<ItemViewModel> Items { get { return items; } }
public MainWindowViewModel()
{
// Populate the view model with some example data.
items.Add(new RectangleViewModel(250, 200));
items.Add(new RectangleViewModel(320, 370));
items.Add(new RectangleViewModel(100, 50));
items.Add(new RectangleViewModel(350, 25));
items.Add(new RectangleViewModel(70, 270));
items.Add(new CircleViewModel(20, 20));
items.Add(new CircleViewModel(300, 270));
items.Add(new CircleViewModel(350, 100));
items.Add(new CircleViewModel(50, 315));
items.Add(new CircleViewModel(100, 170));
}
}
public class ItemViewModel : INotifyPropertyChanged
{
// position coordinates
private double x = 0;
public double X
{
get { return x; }
set
{
if (x != value)
{
x = value;
OnPropertyChanged("X");
}
}
}
private double y = 0;
public double Y
{
get { return y; }
set
{
if (y != value)
{
y = value;
OnPropertyChanged("Y");
}
}
}
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class CircleViewModel : ItemViewModel
{
// Constructors
public CircleViewModel(double x, double y)
{
this.X = x;
this.Y = y;
}
}
public class RectangleViewModel : ItemViewModel
{
// Constructors
public RectangleViewModel(double x, double y)
{
this.X = x;
this.Y = y;
}
}
}
MainWindowViewModel.cs
<Window x:Class="DragShapes.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="600"
xmlns:local="clr-namespace:DragShapes">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type local:RectangleViewModel}" >
<Rectangle Cursor="Hand" Fill="Green" Width="100" Height="100" Margin="10"
MouseLeftButtonDown="shape_MouseLeftButtonDown"
MouseMove="shape_MouseMove"
MouseLeftButtonUp="shape_MouseLeftButtonUp"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:CircleViewModel}" >
<Path Data="M0,0 C0,0 10,100 100,100" Stroke="Gold" StrokeThickness="5" Cursor="Hand"
MouseLeftButtonDown="shape_MouseLeftButtonDown"
MouseLeftButtonUp="shape_MouseLeftButtonUp"
MouseMove="shape_MouseMove"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Canvas x:Name="LayoutRoot" Background="White">
<Ellipse Fill="Blue" HorizontalAlignment="Center" Height="100" Stroke="Black" VerticalAlignment="Center" Width="100" Canvas.Left="200" Canvas.Top="100"
MouseLeftButtonDown="shape_MouseLeftButtonDown"
MouseMove="shape_MouseMove"
MouseLeftButtonUp="shape_MouseLeftButtonUp" />
<Rectangle Fill="Red" Height="100" Stroke="Black" Width="100" HorizontalAlignment="Left" VerticalAlignment="Bottom" Canvas.Left="10" Canvas.Top="10"
MouseLeftButtonDown="shape_MouseLeftButtonDown"
MouseLeftButtonUp="shape_MouseLeftButtonUp"
MouseMove="shape_MouseMove"/>
</Canvas>
<Canvas Grid.Row="1" Background="White" >
<ItemsControl ItemsSource="{Binding Path=Items}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="LightBlue" Width="500" Height="500" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="Green" Width="25" Height="25"
MouseLeftButtonDown="shape_MouseLeftButtonDown"
MouseLeftButtonUp="shape_MouseLeftButtonUp"
MouseMove="shape_MouseMove"/>
</DataTemplate>
</ItemsControl.ItemTemplate>-->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<!--<ItemsControl ItemsSource="{Binding Path=Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>-->
<!--<ItemsControl ItemsSource="{Binding Path=Items}">
--><!--<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>--><!--
</ItemsControl>-->
</Canvas>
</Grid>
</Window>
MainWindow.xaml
{{1}}
答案 0 :(得分:2)
默认的ListBoxItem模板具有活动背景,因此我们需要重置模板,如下所示:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" >
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="LightBlue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
然后,我们需要修改矩形和圆形模板,以便在选择它们时获得选择效果:
<DataTemplate DataType="{x:Type local:RectangleViewModel}" >
<Grid>
<Border CornerRadius="4"
Background="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}},
Path=Background}"/>
<Border Cursor="Hand" Background="Green" CornerRadius="4" Width="100" Height="100" Margin="10"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:CircleViewModel}" >
<Grid>
<Path Data="M0,0 C0,0 10,100 100,100" StrokeThickness="15"
Stroke="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}},
Path=Background}"/>
<Path Data="M0,0 C0,0 10,100 100,100" Stroke="Gold" StrokeThickness="5" Cursor="Hand"/>
</Grid>
</DataTemplate>