I am working on a small state chart editor. I try to implement it in the MVVM pattern.
What I got so far:
My main view
<UserControl.Resources>
<vm:StateChartViewModel x:Key="StateChartViewModel"/>
<DataTemplate DataType="{x:Type vm:StateViewModel}">
<views:StateWidget/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TransitionViewModel}">
<views:TransitionWidget/>
</DataTemplate>
</UserControl.Resources>
<Canvas Background="Transparent"
DataContext="{StaticResource StateChartViewModel}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<command:EventToCommand Command="{Binding CreateStateCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ItemsControl Canvas.Left="0"
Canvas.Top="0"
ItemsSource="{Binding Transitions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="0" />
<Setter Property="Canvas.Top" Value="0" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<ItemsControl Canvas.Left="0"
Canvas.Top="0"
ItemsSource="{Binding States}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="0"/>
<Setter Property="Canvas.Top" Value="0"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Canvas>
The DataTemplates which I have set for the StateViewModel and the TransitionViewModel are views of these viewModels
StateView (StateWidget)
<UserControl.Resources>
<vm:StateViewModel x:Key="StateViewModel"/>
</UserControl.Resources>
<Grid x:Name="XMainGrid"
DataContext="{StaticResource StateViewModel}">
<Rectangle Fill="CornflowerBlue"
RadiusX="5" RadiusY="5"
ClipToBounds="True">
</Rectangle>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBox Text="{Binding Path=State.Name}"
Background="Transparent"/>
<Polygon Points="0,0 20,0 10,10"
Fill="DarkSlateGray"
Margin="10,5,0,0"/>
</StackPanel>
</Grid>
TransitionView (TransitionWidget)
<UserControl.Resources>
<vm:TransitionViewModel x:Key="TransitionViewModel"/>
</UserControl.Resources>
<Canvas DataContext="{StaticResource TransitionViewModel}">
<Line X1="{Binding SourceState.Position.X}"
Y1="{Binding SourceState.Position.Y}"
X2="{Binding TargetState.Position.X}"
Y2="{Binding TargetState.Position.Y}"
Stroke="DarkGreen"
StrokeThickness="4"
/>
</Canvas>
In the StateChartViewModel I have 2 ObservableCollections with StateViewModels and TransitionModels
private ObservableCollection<StateViewModel> _states;
public ObservableCollection<StateViewModel> States
{
get
{
if (_states == null)
_states = new ObservableCollection<StateViewModel>();
return _states;
}
}
private ObservableCollection<TransitionViewModel> _transitions;
public ObservableCollection<TransitionViewModel> Transitions
{
get
{
if (_transitions == null)
_transitions = new ObservableCollection<TransitionViewModel>();
return _transitions;
}
}
private RelayCommand<MouseEventArgs> _createStateCommand;
public ICommand CreateStateCommand
{
get
{
if (_createStateCommand == null)
_createStateCommand = new RelayCommand<MouseEventArgs>(AddNewState);
return _createStateCommand;
}
}
private void AddNewState(MouseEventArgs e)
{
var newState = new StateViewModel();
_states.Add(newState);
}
My problem is that the canvas in the main view doesn't show any of that items when I add StateViewModels to States aswell with the transitions. When adding SateWidgets directly to the canvas' children they are appear in the canvas. But I think there have to be a solution without doing it manually.
Edit
The StateView (StateWidget) and the TransitionView (TransitionWidget) should both be displayed in the same canvas! StateViewModels should be displayed as StateWidgets and TransitionViewModels as Transitionwidgets.
MainCanvas
/--------------\ TransitionWidget /--------------\
| StateWidget1 |------------------------| StateWidget2 |
\--------------/ \--------------/