【发布时间】:2014-11-11 05:00:13
【问题描述】:
我正在开发一个小型状态图编辑器。 我尝试在 MVVM 模式中实现它。
到目前为止我得到了什么:
我的主要观点
<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>
我为 StateViewModel 和 TransitionViewModel 设置的 DataTemplates 是这些 viewModel 的视图
状态视图(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>
在 StateChartViewModel 中,我有 2 个带有 StateViewModels 和 TransitionModels 的 ObservableCollections
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);
}
我的问题是,当我将 StateViewModels 添加到状态以及转换时,主视图中的画布没有显示任何这些项目。将 SateWidgets 直接添加到画布的子项时,它们会出现在画布中。但我认为必须有一个解决方案,而无需手动执行。
编辑
StateView (StateWidget) 和 TransitionView (TransitionWidget) 应该都显示在同一个画布上! StateViewModels 应显示为 StateWidgets,TransitionViewModels 应显示为 Transitionwidgets。
MainCanvas
/--------------\ TransitionWidget /--------------\
| StateWidget1 |------------------------| StateWidget2 |
\--------------/ \--------------/
【问题讨论】:
-
您好,您在 StateView 和 TransistionView 上都设置了数据上下文,同时您将这些数据的集合存储在不同的虚拟机中。从 StateView 和 TransistionView 中移除 datacontext,因此列表中的项目设置为 datacontext。
标签: wpf xaml mvvm binding itemscontrol