基于该问题答案的项目:
Graph nodes coordinates evaluation
并使用MVVM Light Toolkit我正在尝试开发一个应用程序,它不仅允许用户在画布周围移动项目,还可以调整它们的大小。以下是我到目前为止的情况:
http://screenshooter.net/4766406/tfcqpjw
主窗口XAML
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
xmlns:localvm="clr-namespace:WpfApplication2.ViewModel"
Title="MainWindow" Height="350" Width="927.985" x:Name="view">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="EditorStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<StackPanel Width="95" DockPanel.Dock="Left" Margin="5,0,0,0">
<local:ButtonsPanel/>
</StackPanel>
<Grid Margin="10">
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<CompositeCollection x:Key="Col">
<CollectionContainer Collection="{Binding DataContext.Notes,Source={x:Reference view}}"/>
</CompositeCollection>
<DataTemplate DataType="{x:Type localvm:NoteViewModel}">
<Grid>
<Thumb DragDelta="Thumb_Drag"
IsEnabled="{Binding IsSelected,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas>
<Path Fill="#FFAA0000" Data="{Binding ShapeGeometry}" Stretch="Fill" x:Name="Path"/>
</Canvas>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter TargetName="Path" Property="Fill" Value="Red"/>
</DataTrigger>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="Path" Property="Fill" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
</DataTemplate>
</Grid.Resources>
<ListBox SelectedItem="{Binding SelectedNote}"
PreviewMouseMove="ListBox_PreviewMouseMove"
PreviewMouseDown="ListBox_PreviewMouseDown">
<ListBox.Template ... > <!-- Collapsed -->
</ListBox.Template>
<ListBox.ItemsSource>
<StaticResource ResourceKey="Col"/>
</ListBox.ItemsSource>
<ListBox.ItemsPanel ...> <!-- Collapsed -->
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<!-- Moves the object -->
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter x:Name="Content"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</DockPanel>
Thumb的DragDelta来自MainWindow代码后面的+构造函数:
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
private void Thumb_Drag(object sender, DragDeltaEventArgs e)
{
var thumb = sender as Thumb;
if (thumb == null)
return;
var note = thumb.DataContext as NoteViewModel;
if (note == null)
return;
note.X += e.HorizontalChange;
note.Y += e.VerticalChange;
}
MainViewModel中的重要属性和方法:
public class MainViewModel : ViewModelBase
{
private ObservableCollection<NoteViewModel> _notes;
public ObservableCollection<NoteViewModel> Notes
{
get { return _notes ?? (_notes = new ObservableCollection<NoteViewModel>()); }
}
private NoteViewModel _selectedNote;
public NoteViewModel SelectedNote {...}
public MainViewModel()
{
_notes = new ObservableCollection<NoteViewModel>(NotesDataSource.GetRandomNotes());
}
#region Creating New Notes
private bool _creatingNewNote;
public bool CreatingNewNote
{
get { return _creatingNewNote; }
set
{
_creatingNewNote = value;
RaisePropertyChanged("CreatingNewNote");
if (value)
CreateNewNote();
else
RemoveNewObjects();
}
}
public void CreateNewNote()
{
var newnote = new NoteViewModel()
{
Name = "Note" + (Notes.Count + 1),
IsNew = true
};
Notes.Add(newnote);
SelectedNote = newnote;
}
public void RemoveNewObjects()
{
Notes.Where(x => x.IsNew).ToList().ForEach(x => Notes.Remove(x));
}
#endregion
}
NoteViewModel:
public class NoteViewModel : ViewModelBase
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
#region Coordinates & Size
private double _x;
public double X { ...}
private double _y;
public double Y {...}
private double _width;
public double Width {...}
private double _height;
public double Height {...}
#endregion
#region Shape Geometry
private string _shapeGeometry;
public string ShapeGeometry {...}
#endregion
#region Selection Properties
private bool _isNew;
public bool IsNew {...}
#endregion
public NoteViewModel()
{
Random random = new Random();
var notenumber = random.Next(0, 100);
var notename = "Note" + notenumber;
Name = notename;
X = 10;
Y = 10;
ShapeGeometry = "M39.967 23.133c-0.211 0.189-0.523 0.199-0.748 0.028l-7.443-5.664l-3.526 21.095c-0.013 0.08-0.042 0.153-0.083 0.219 c-0.707 3.024-4.566 5.278-9.104 5.278c-5.087 0-9.226-2.817-9.226-6.28s4.138-6.281 9.226-6.281c2.089 0 4.075 0.466 5.689 1.324 l4.664-26.453c0.042-0.242 0.231-0.434 0.475-0.479c0.237-0.041 0.485 0.068 0.611 0.28l9.581 16.192 C40.227 22.637 40.178 22.945 39.967 23.133z";
Width = CalculateSize("w");
Height = CalculateSize("h");
}
private double CalculateSize(string s) {...}
Thumb允许移动,我试图将上面的例子与这里的例子结合起来(没有Adorners,他们看起来非常复杂,就像我找到的所有其他例子一样):http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part
然而,经过相当长时间的绞尽脑汁之后,我无法找到可行的解决方案。如何调整项目大小?请帮助一位遇险的少女!