Reputation: 106
i'm creating an application in WPF using MVVM and i'm in a dificult situation becouse i can not bind a command to a Canvases ClickEvent.
I want to put some rectangels on the Canvas and save thair position to a database, but if i placed to the wrong place and i click on it it would move along the cursor until the next click.
XAML file:
<UserControl x:Class="View.TheaterManageRoom"
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:local="clr-namespace:View"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<StackPanel Margin="5"
Orientation="Horizontal">
<Label Content="RoomName:"/>
<TextBox VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
Width="100"/>
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical">
<Label Margin="5"
Content="Seat multiplier:"/>
<TextBox Margin="5" Text="{Binding TheaterManageRoomMultiplier, UpdateSourceTrigger=PropertyChanged}"/>
<Button Margin="5">Add Seat</Button>
<Button Margin="5">Stage</Button>
<Button Margin="5">Save</Button>
</StackPanel>
<ItemsControl ItemsSource="{Binding TheaterManageRoomPoints}"
Margin="10"
Grid.Column="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"
Background="White"
MouseUp="{Binding TheaterManageRoomMouseClick}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{Binding BorderColor}" Background="{Binding FillColor}" BorderThickness="1" Width="{Binding Width}" Height="{Binding Height}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--<Canvas Name="TheaterManageRoomCanvas"
Margin="10"
Background="White"
Grid.Column="1"></Canvas>-->
</Grid>
</Grid>
The part from the MainVindowViewModel that is actualy used in this part:
#region TheaterManageRoom
private Visibility theaterManageRoomVisibility = Visibility.Hidden;
public Visibility TheaterManageRoomVisibility
{
get { return theaterManageRoomVisibility; }
set
{
theaterManageRoomVisibility = value;
RaisePropertyChanged("TheaterManageRoomVisibility");
}
}
private string theaterManageRoomMultiplier = "";
public string TheaterManageRoomMultiplier
{
get { return theaterManageRoomMultiplier; }
set
{
Regex r = new Regex(@"(^[0-9]+(\.[0-9]*)*$)|(^$)");
if (r.Match(value).Success)
{
theaterManageRoomMultiplier = value;
}
RaisePropertyChanged("TheaterManageRoomMultiplier");
}
}
public class RectItem
{
public RectItem(double X, double Y, double Width, double Height) {
this.X = X;
this.Y = Y;
this.Width = Width;
this.Height = Height;
BorderColor = new SolidColorBrush(Colors.Black);
FillColor = new SolidColorBrush(Colors.Wheat);
}
public SolidColorBrush BorderColor { get; set; }
public SolidColorBrush FillColor { get; set; }
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
}
private ObservableCollection<RectItem> theaterManageRoomPoints;
public ObservableCollection<RectItem> TheaterManageRoomPoints {
get { return theaterManageRoomPoints; }
set {
theaterManageRoomPoints = value;
RaisePropertyChanged("TheaterManageRoomPoints");
}
}
public void TheaterManageRoomLoadElements()
{
TheaterManageRoomPoints = new ObservableCollection<RectItem>();
TheaterManageRoomPoints.Add(new RectItem(10,10,5,5));
}
public ICommand TheaterManageRoomMouseClick
{
get { return new RelayCommand(TheaterManageRoomMouseClickFunc); }
}
private void TheaterManageRoomMouseClickFunc() {
TheaterManageRoomPoints.Add(new RectItem(10, 10, 5, 5));
}
#endregion
Upvotes: 2
Views: 1615
Reputation: 106
Ok, i solved the problem, just needed some libs and a litle work on the code. With the NuGetManager i installed the Unofficial.Blend.Interactivity (in the xaml file the 'i') package and the MvvmLightLibs (in the xaml file the 'mvvm') package.
The in xaml file I added this lines:
This two lines at the top:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
And wit this in the actual code:
<Canvas IsItemsHost="True"
Background="White">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<mvvm:EventToCommand Command="{Binding TheaterManageRoomClickOnCanvas}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
And in the MainVindowViewModel
public ICommand TheaterManageRoomClickOnCanvas
{
get { return new RelayCommand<EventArgs>(TheaterManageRoomClickOnCanvasFunc); }
}
private void TheaterManageRoomClickOnCanvasFunc(EventArgs args) {
MouseEventArgs e = (MouseEventArgs)args;
var position = e.GetPosition(e.Device.Target);
TheaterManageRoomPoints.Add(new RectItem(position.X, position.Y));
}
Upvotes: 2