Files
APIVisualExecutor/Examples/Nodify.StateMachine/MainWindow.xaml
Ankitkumar Satapara 21aaef6776 Add project files.
2026-04-17 22:31:58 +05:30

745 lines
48 KiB
XML

<Window x:Class="Nodify.StateMachine.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Nodify.StateMachine"
xmlns:shared="clr-namespace:Nodify;assembly=Nodify.Shared"
xmlns:nodify="https://miroiu.github.io/nodify"
ResizeMode="CanResizeWithGrip"
mc:Ignorable="d"
Background="{DynamicResource NodifyEditor.BackgroundBrush}"
Foreground="{DynamicResource ForegroundBrush}"
Title="State Machine Editor"
Height="500"
Width="930">
<Window.DataContext>
<local:StateMachineViewModel />
</Window.DataContext>
<Window.Resources>
<shared:BindingProxy x:Key="EditorProxy"
DataContext="{Binding}" />
<shared:BindingProxy x:Key="BlackboardProxy"
DataContext="{Binding Blackboard}" />
<local:ConnectorOffsetConverter x:Key="ConnectorOffsetConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ScrollViewer CanContentScroll="True"
PreviewKeyDown="ScrollViewer_PreviewKeyDown"
Grid.Column="1">
<nodify:NodifyEditor x:Name="Editor"
ItemsSource="{Binding States}"
SelectedItem="{Binding SelectedState}"
SelectedItems="{Binding SelectedStates}"
Connections="{Binding Transitions}"
PendingConnection="{Binding PendingTransition}"
DisconnectConnectorCommand="{Binding DisconnectStateCommand}"
ConnectionCompletedCommand="{Binding CreateTransitionCommand}"
RemoveConnectionCommand="{Binding DeleteTransitionCommand}">
<nodify:NodifyEditor.PendingConnectionTemplate>
<DataTemplate DataType="{x:Type local:TransitionViewModel}">
<nodify:PendingConnection Source="{Binding Source, Mode=OneWayToSource}"
Target="{Binding Target, Mode=OneWayToSource}"
StrokeDashArray=""
EnablePreview="True">
<nodify:PendingConnection.Template>
<ControlTemplate TargetType="{x:Type nodify:PendingConnection}">
<nodify:LineConnection Source="{TemplateBinding SourceAnchor}"
Target="{TemplateBinding TargetAnchor}"
StrokeThickness="{TemplateBinding StrokeThickness}"
StrokeDashArray="{TemplateBinding StrokeDashArray}"
SourceOffset="{Binding Source.Size, Converter={StaticResource ConnectorOffsetConverter}, ConverterParameter=5}"
Spacing="0"
SourceOffsetMode="Edge"
TargetOffsetMode="None" />
</ControlTemplate>
</nodify:PendingConnection.Template>
</nodify:PendingConnection>
</DataTemplate>
</nodify:NodifyEditor.PendingConnectionTemplate>
<nodify:NodifyEditor.ConnectionTemplate>
<DataTemplate DataType="{x:Type local:TransitionViewModel}">
<nodify:LineConnection Source="{Binding Source.Anchor}"
Target="{Binding Target.Anchor}"
SourceOffset="{Binding Source.Size, Converter={StaticResource ConnectorOffsetConverter}, ConverterParameter=5}"
TargetOffset="{Binding Target.Size, Converter={StaticResource ConnectorOffsetConverter}, ConverterParameter=5}"
Spacing="0"
SourceOffsetMode="Edge"
TargetOffsetMode="Edge"
OutlineThickness="5"
Tag="{Binding}">
<nodify:LineConnection.Style>
<Style TargetType="{x:Type nodify:LineConnection}"
BasedOn="{StaticResource {x:Type nodify:LineConnection}}">
<Setter Property="OutlineBrush"
Value="Transparent" />
<Setter Property="StrokeThickness"
Value="3" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}"
Value="True">
<Setter Property="Stroke"
Value="{DynamicResource ActiveStateBrush}" />
<Setter Property="StrokeThickness"
Value="6" />
</DataTrigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="OutlineBrush">
<Setter.Value>
<SolidColorBrush Color="{StaticResource LineConnection.StrokeColor}"
Opacity="0.15" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</nodify:LineConnection.Style>
<nodify:LineConnection.ContextMenu>
<ContextMenu DataContext="{Binding DataContext, Source={StaticResource EditorProxy}}">
<MenuItem Header="_Delete"
Icon="{StaticResource DeleteIcon}"
Command="{Binding DeleteTransitionCommand}"
CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>
</nodify:LineConnection.ContextMenu>
</nodify:LineConnection>
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
<nodify:NodifyEditor.ItemTemplate>
<DataTemplate DataType="{x:Type local:StateViewModel}">
<!--If IsConnected is false, Anchor won't be updated-->
<nodify:StateNode Content="{Binding}"
IsConnected="True"
Anchor="{Binding Anchor, Mode=OneWayToSource}">
<nodify:StateNode.ContentTemplate>
<DataTemplate DataType="{x:Type local:StateViewModel}">
<shared:EditableTextBlock Text="{Binding Name}"
IsEditing="{Binding IsRenaming}"
IsEditable="{Binding IsEditable}"
MaxLength="30" />
</DataTemplate>
</nodify:StateNode.ContentTemplate>
<nodify:StateNode.Style>
<Style TargetType="{x:Type nodify:StateNode}"
BasedOn="{StaticResource {x:Type nodify:StateNode}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditable}"
Value="False">
<Setter Property="BorderBrush"
Value="{DynamicResource ReadOnlyStateBrush}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsActive}"
Value="True">
<Setter Property="BorderBrush"
Value="{DynamicResource ActiveStateBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</nodify:StateNode.Style>
</nodify:StateNode>
</DataTemplate>
</nodify:NodifyEditor.ItemTemplate>
<nodify:NodifyEditor.ItemContainerStyle>
<Style TargetType="{x:Type nodify:ItemContainer}"
BasedOn="{StaticResource {x:Type nodify:ItemContainer}}">
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="Location"
Value="{Binding Location}" />
<Setter Property="ActualSize"
Value="{Binding Size, Mode=OneWayToSource}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding DataContext, Source={StaticResource EditorProxy}}">
<MenuItem Header="_Delete"
Icon="{StaticResource DeleteIcon}"
Command="{Binding DeleteSelectionCommand}" />
<MenuItem Header="Di_sconnect"
Icon="{StaticResource DisconnectIcon}"
Command="{Binding DisconnectSelectionCommand}" />
<MenuItem Header="_Rename"
Icon="{StaticResource RenameIcon}"
Command="{Binding RenameStateCommand}" />
<MenuItem Header="_Lock"
Icon="{StaticResource LockIcon}"
Command="{x:Static nodify:EditorCommands.LockSelection}" />
<MenuItem Header="_Unlock"
Icon="{StaticResource UnlockIcon}"
Command="{x:Static nodify:EditorCommands.UnlockSelection}" />
<MenuItem Header="_Alignment"
Icon="{StaticResource AlignTopIcon}">
<MenuItem Header="_Top"
Icon="{StaticResource AlignTopIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Top" />
<MenuItem Header="_Left"
Icon="{StaticResource AlignLeftIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Left" />
<MenuItem Header="_Bottom"
Icon="{StaticResource AlignBottomIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Bottom" />
<MenuItem Header="_Right"
Icon="{StaticResource AlignRightIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Right" />
<MenuItem Header="_Middle"
Icon="{StaticResource AlignMiddleIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Middle" />
<MenuItem Header="_Center"
Icon="{StaticResource AlignCenterIcon}"
Command="{x:Static nodify:EditorCommands.Align}"
CommandParameter="Center" />
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</nodify:NodifyEditor.ItemContainerStyle>
<nodify:NodifyEditor.ContextMenu>
<ContextMenu DataContext="{Binding DataContext, Source={StaticResource EditorProxy}}">
<MenuItem Header="_Add State"
Icon="{StaticResource AddStateIcon}"
InputGestureText="Shift+A"
Command="{Binding AddStateCommand}"
CommandParameter="{Binding PlacementTarget.MouseLocation, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
<MenuItem Header="_Delete"
Icon="{StaticResource DeleteIcon}"
InputGestureText="Delete"
Command="{Binding DeleteSelectionCommand}" />
<Separator Background="{DynamicResource BorderBrush}" />
<MenuItem Header="_Select All"
Icon="{StaticResource SelectAllIcon}"
InputGestureText="Ctrl+A"
Command="{x:Static nodify:EditorCommands.SelectAll}" />
</ContextMenu>
</nodify:NodifyEditor.ContextMenu>
<nodify:NodifyEditor.InputBindings>
<KeyBinding Key="Delete"
Command="{Binding DeleteSelectionCommand}" />
<KeyBinding Key="A"
Modifiers="Shift"
Command="{Binding AddStateCommand}"
CommandParameter="{Binding MouseLocation, RelativeSource={RelativeSource AncestorType={x:Type nodify:NodifyEditor}}}" />
</nodify:NodifyEditor.InputBindings>
</nodify:NodifyEditor>
</ScrollViewer>
<!--TOOLBAR-->
<Border CornerRadius="2"
Background="{DynamicResource PanelBackgroundBrush}"
BorderThickness="0 0 0 1"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="10 0"
Grid.Column="1">
<StackPanel Orientation="Horizontal">
<Button Command="{Binding PauseCommand}">
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource IconButton}">
<Setter Property="Content"
Value="{StaticResource PauseIcon}" />
<Setter Property="ToolTip"
Value="Pause" />
<Style.Triggers>
<DataTrigger Binding="{Binding Runner.State}"
Value="Stopped">
<Setter Property="Visibility"
Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding Runner.State}"
Value="Paused">
<Setter Property="Content"
Value="{StaticResource UnpauseIcon}" />
<Setter Property="ToolTip"
Value="Continue" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Command="{Binding RunCommand}"
Style="{StaticResource IconButton}">
<StackPanel Orientation="Horizontal">
<ContentPresenter DataContext="{Binding}"
Margin="0 0 4 0">
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="Content"
Value="{StaticResource StopIcon}" />
<Setter Property="ToolTip"
Value="Stop" />
<Style.Triggers>
<DataTrigger Binding="{Binding Runner.State}"
Value="Stopped">
<Setter Property="Content"
Value="{StaticResource RunIcon}" />
<Setter Property="ToolTip"
Value="Run" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</Button>
<Separator Height="Auto"
BorderThickness="0 0 1 0" />
<Button Content="{StaticResource ZoomInIcon}"
Command="{x:Static nodify:EditorCommands.ZoomIn}"
CommandTarget="{Binding ElementName=Editor}"
ToolTip="Zoom In"
Style="{StaticResource IconButton}" />
<Button Content="{StaticResource ZoomOutIcon}"
Command="{x:Static nodify:EditorCommands.ZoomOut}"
CommandTarget="{Binding ElementName=Editor}"
ToolTip="Zoom Out"
Style="{StaticResource IconButton}" />
<Button Style="{StaticResource IconButton}"
Content="{StaticResource ThemeIcon}"
Command="{Binding Source={x:Static shared:ThemeManager.SetNextThemeCommand}}"
ToolTip="Change theme" />
</StackPanel>
</Border>
<!--Settings-->
<Expander HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
HorizontalAlignment="Left"
Background="{DynamicResource PanelBackgroundBrush}"
Padding="0 1 4 3"
IsExpanded="True"
ExpandDirection="Left">
<Expander.Style>
<Style TargetType="{x:Type Expander}"
BasedOn="{StaticResource {x:Type Expander}}">
<Setter Property="Tag"
Value="{StaticResource ExpandRightIcon}" />
<Style.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter Property="Tag"
Value="{StaticResource ExpandLeftIcon}" />
</Trigger>
</Style.Triggers>
</Style>
</Expander.Style>
<Border BorderBrush="{DynamicResource BackgroundBrush}"
BorderThickness="1"
Width="300"
Padding="10"
HorizontalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<!--TRANSITIONS-->
<ScrollViewer Visibility="{Binding SelectedState, Converter={shared:BooleanToVisibilityConverter Negate=True}}"
VerticalScrollBarVisibility="Auto"
Grid.Row="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Transitions"
Foreground="{DynamicResource ForegroundBrush}"
FontWeight="Bold"
FontSize="16" />
<Separator Height="2"
Width="Auto"
Margin="0 2 0 5"
Grid.Row="1" />
<ItemsControl ItemsSource="{Binding Transitions}"
Grid.Row="2"
Focusable="False">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:TransitionViewModel}">
<Expander BorderThickness="0 0 0 1"
Padding="0 5 0 0"
IsExpanded="True"
BorderBrush="{DynamicResource BackgroundBrush}">
<Expander.Style>
<Style TargetType="{x:Type Expander}"
BasedOn="{StaticResource {x:Type Expander}}">
<Setter Property="Tag"
Value="{StaticResource ExpandRightIcon}" />
<Style.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter Property="Tag"
Value="{StaticResource ExpandDownIcon}" />
</Trigger>
</Style.Triggers>
</Style>
</Expander.Style>
<Expander.Header>
<TextBlock>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground"
Value="{DynamicResource ForegroundBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}"
Value="True">
<Setter Property="Foreground"
Value="{DynamicResource ActiveStateBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<Run Text="{Binding Source.Name, Mode=OneWay}" />
<Run Text="🠚" />
<Run Text="{Binding Target.Name, Mode=OneWay}" />
</TextBlock>
</Expander.Header>
<Border HorizontalAlignment="Stretch">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="ConditionName" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--CONDITION-->
<TextBlock Text="Condition"
Margin="0 0 10 0"
VerticalAlignment="Center" />
<ComboBox ItemsSource="{Binding DataContext.Blackboard.Conditions, Source={StaticResource EditorProxy}}"
SelectedItem="{Binding ConditionReference}"
DisplayMemberPath="Name"
Grid.Column="1" />
<!--INPUT-->
<ItemsControl ItemsSource="{Binding Condition.Input}"
Padding="0 5 0 0"
Grid.Row="1"
Grid.ColumnSpan="2">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:BlackboardKeyViewModel}">
<local:BlackboardKeyEditorView Margin="0 0 0 2">
<local:BlackboardKeyEditorView.DataContext>
<MultiBinding Converter="{local:BlackboardKeyEditorConverter CanChangeInputType=True}">
<Binding Source="{StaticResource BlackboardProxy}"
Path="DataContext.Keys" />
<Binding BindsDirectlyToSource="True" />
</MultiBinding>
</local:BlackboardKeyEditorView.DataContext>
</local:BlackboardKeyEditorView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Grid.Row="2"
Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="From: "
VerticalAlignment="Center" />
<Button Style="{StaticResource IconButton}"
Command="{x:Static nodify:EditorCommands.BringIntoView}"
CommandParameter="{Binding Source.Location}"
CommandTarget="{Binding ElementName=Editor}"
Foreground="DodgerBlue">
<TextBlock Text="{Binding Source.Name}"
TextDecorations="Underline" />
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal"
Grid.Column="1">
<TextBlock Text="To: "
VerticalAlignment="Center" />
<Button Style="{StaticResource IconButton}"
Command="{x:Static nodify:EditorCommands.BringIntoView}"
CommandParameter="{Binding Target.Location}"
CommandTarget="{Binding ElementName=Editor}"
Foreground="DodgerBlue">
<TextBlock Text="{Binding Target.Name}"
TextDecorations="Underline" />
</Button>
</StackPanel>
</Grid>
</Grid>
</Border>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</ScrollViewer>
<!--STATES-->
<Grid Visibility="{Binding SelectedState, Converter={shared:BooleanToVisibilityConverter}}"
Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--STATE NAME-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<shared:EditableTextBlock Text="{Binding SelectedState.Name}"
IsEditing="{Binding IsChecked, ElementName=EditStateName}"
IsEditable="{Binding SelectedState.IsEditable}"
Foreground="{DynamicResource ForegroundBrush}"
FontWeight="Bold"
FontSize="16"
MaxLength="20" />
<CheckBox x:Name="EditStateName"
Visibility="{Binding SelectedState.IsEditable, Converter={shared:BooleanToVisibilityConverter}}"
Content="{StaticResource EditIcon}"
Style="{StaticResource IconCheckBox}"
Grid.Column="1" />
</Grid>
<Separator Height="2"
Width="Auto"
Margin="0 2 0 10"
Grid.Row="1" />
<ScrollViewer Visibility="{Binding SelectedState.Action, Converter={shared:BooleanToVisibilityConverter}}"
VerticalScrollBarVisibility="Auto"
Grid.Row="2">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--ACTION-->
<TextBlock Text="Action"
Margin="0 0 10 0"
VerticalAlignment="Center" />
<ComboBox ItemsSource="{Binding Blackboard.Actions}"
SelectedItem="{Binding SelectedState.ActionReference}"
IsEnabled="{Binding SelectedState.IsEditable}"
DisplayMemberPath="Name"
Grid.Column="1" />
<!--INPUT-->
<Expander Margin="0 5 0 0"
Padding="0 5 0 0"
Grid.Row="1"
Grid.ColumnSpan="2"
BorderThickness="0 0 0 1"
Header="Input"
FontWeight="Bold"
IsExpanded="True"
BorderBrush="{DynamicResource BackgroundBrush}"
Visibility="{Binding SelectedState.Action.Input.Count, Converter={shared:BooleanToVisibilityConverter}}">
<Expander.Style>
<Style TargetType="{x:Type Expander}"
BasedOn="{StaticResource {x:Type Expander}}">
<Setter Property="Tag"
Value="{StaticResource ExpandRightIcon}" />
<Style.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter Property="Tag"
Value="{StaticResource ExpandDownIcon}" />
</Trigger>
</Style.Triggers>
</Style>
</Expander.Style>
<ItemsControl ItemsSource="{Binding SelectedState.Action.Input}"
FontWeight="Normal">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:BlackboardKeyViewModel}">
<local:BlackboardKeyEditorView Margin="0 0 0 2">
<local:BlackboardKeyEditorView.DataContext>
<MultiBinding Converter="{local:BlackboardKeyEditorConverter CanChangeInputType=True}">
<Binding Source="{StaticResource BlackboardProxy}"
Path="DataContext.Keys" />
<Binding BindsDirectlyToSource="True" />
</MultiBinding>
</local:BlackboardKeyEditorView.DataContext>
</local:BlackboardKeyEditorView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
<!--OUTPUT-->
<Expander Margin="0 5 0 0"
Padding="0 5 0 0"
Grid.Row="2"
Grid.ColumnSpan="2"
Header="Output"
FontWeight="Bold"
BorderThickness="0 0 0 1"
IsExpanded="True"
BorderBrush="{DynamicResource BackgroundBrush}"
Visibility="{Binding SelectedState.Action.Output.Count, Converter={shared:BooleanToVisibilityConverter}}">
<Expander.Style>
<Style TargetType="{x:Type Expander}"
BasedOn="{StaticResource {x:Type Expander}}">
<Setter Property="Tag"
Value="{StaticResource ExpandRightIcon}" />
<Style.Triggers>
<Trigger Property="IsExpanded"
Value="True">
<Setter Property="Tag"
Value="{StaticResource ExpandDownIcon}" />
</Trigger>
</Style.Triggers>
</Style>
</Expander.Style>
<ItemsControl ItemsSource="{Binding SelectedState.Action.Output}"
FontWeight="Normal">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:BlackboardKeyViewModel}">
<local:BlackboardKeyEditorView Margin="0 0 0 2">
<local:BlackboardKeyEditorView.DataContext>
<MultiBinding Converter="{local:BlackboardKeyEditorConverter CanChangeInputType=False}">
<Binding Source="{StaticResource BlackboardProxy}"
Path="DataContext.Keys" />
<Binding BindsDirectlyToSource="True" />
</MultiBinding>
</local:BlackboardKeyEditorView.DataContext>
</local:BlackboardKeyEditorView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
</Grid>
</ScrollViewer>
</Grid>
<!--BLACKBOARD-->
<Grid IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<shared:EditableTextBlock Text="{Binding Name}"
IsEditing="{Binding IsChecked, ElementName=EditName}"
Foreground="{DynamicResource ForegroundBrush}"
FontWeight="Bold"
FontSize="16"
MaxLength="20" />
<StackPanel Orientation="Horizontal"
Grid.Column="1">
<CheckBox x:Name="EditName"
Content="{StaticResource EditIcon}"
ToolTip="Edit Name"
Style="{StaticResource IconCheckBox}" />
<Button Content="{StaticResource AddKeyIcon}"
Command="{Binding Blackboard.AddKeyCommand}"
ToolTip="Add New Key"
Style="{StaticResource IconButton}" />
</StackPanel>
</Grid>
<Separator Height="2"
Width="Auto"
Margin="0 2 0 10"
Grid.Row="1" />
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
Grid.Row="2">
<ItemsControl ItemsSource="{Binding Blackboard.Keys}"
Focusable="False">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:BlackboardKeyViewModel}">
<Grid Margin="0 0 0 2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition SharedSizeGroup="Actions" />
</Grid.ColumnDefinitions>
<local:BlackboardKeyEditorView>
<local:BlackboardKeyEditorView.DataContext>
<MultiBinding Converter="{local:BlackboardKeyEditorConverter CanChangeInputType=False}">
<Binding Source="{StaticResource BlackboardProxy}"
Path="DataContext.Keys" />
<Binding BindsDirectlyToSource="True" />
<Binding ElementName="EditKeyName"
Path="IsChecked" />
</MultiBinding>
</local:BlackboardKeyEditorView.DataContext>
</local:BlackboardKeyEditorView>
<StackPanel Orientation="Horizontal"
Grid.Column="3">
<CheckBox x:Name="EditKeyName"
Content="{StaticResource EditIcon}"
ToolTip="Edit Name"
Style="{StaticResource IconCheckBox}" />
<Button Content="{StaticResource RemoveKeyIcon}"
Command="{Binding DataContext.Blackboard.RemoveKeyCommand, Source={StaticResource EditorProxy}}"
CommandParameter="{Binding}"
Style="{StaticResource IconButton}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
</Border>
</Expander>
</Grid>
</Window>