wpf主界面游戏引擎实现

2.GameEntityView.xaml

<UserControl x:Class="PrimalEditor.Editors.GameEntityView"

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:PrimalEditor.Editors"

xmlns:vm="clr-namespace:PrimalEditor.Components"

mc:Ignorable="d" Background="{StaticResource Editor.Window.GrayBrush3}"

d:DesignHeight="450" d:DesignWidth="800">

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">

<ScrollViewer.Style>

<Style TargetType="ScrollViewer">

<Style.Triggers>

<Trigger Property="DataContext" Value="{x:Null}">

<Setter Property="Visibility" Value="Collapsed"/>

</Trigger>

</Style.Triggers>

</Style>

</ScrollViewer.Style>

<StackPanel>

<Border Height="32">

<ToggleButton x:Name="addComponent" VerticalAlignment="Center"

HorizontalAlignment="Left" Margin="5,0,0,0">

<ToggleButton.Content>

<DockPanel>

<TextBlock Text="Add Component" Margin="5,0"/>

<Path Margin="3,0,2,0"

Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"

HorizontalAlignment="Center" Fill="Black"

VerticalAlignment="Center"

/>

</DockPanel>

</ToggleButton.Content>

</ToggleButton>

</Border>

<Grid>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="78"/>

<ColumnDefinition/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

<TextBlock Text="Name" Grid.Column="0" Margin="5,0,0,0"/>

<TextBox Text="{Binding Name}" Grid.Column="1" Tag="{Binding RenameCommand}"/>

<StackPanel Orientation="Horizontal" Grid.Column="2">

<TextBlock Text="Enabled" Margin="5,0,0,0"/>

<CheckBox IsChecked="{Binding IsEnabled}" Command="{Binding IsEnabledCommand}"

CommandParameter="{Binding IsChecked,RelativeSource={RelativeSource Self}}"

Margin="5,0" VerticalAlignment="Center"/>

</StackPanel>

</Grid>

<ItemsControl ItemsSource="{Binding Components}">

<ItemsControl.ItemsPanel>

<ItemsPanelTemplate>

<StackPanel/>

</ItemsPanelTemplate>

</ItemsControl.ItemsPanel>

</ItemsControl>

</StackPanel>

</ScrollViewer>

</UserControl>

2.GameEntityView.xaml.cs

using PrimalEditor.Components;

using PrimalEditor.GameProject;

using PrimalEditor.Utilities;

using System.Globalization;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Controls.Primitives;

using System.Windows.Data;

using System.Windows.Input;

namespace PrimalEditor.Editors

{

public class NullableBoolToBoolConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

{

return value is bool b && b == true;

}

}

/// <summary>

/// GameEntityView.xaml 的交互逻辑

/// </summary>

public partial class GameEntityView : UserControl

{

private Action _undoAction;

private string _propertyName;

public static GameEntityView Instance { get; private set; }

public GameEntityView()

{

InitializeComponent();

DataContext = null;

Instance = this;

DataContextChanged += (_, __) =>

{

if (DataContext != null)

{

(DataContext as MSEntity).PropertyChanged += (s, e) => _propertyName = e.PropertyName;

}

};

}

private Action GetRenameAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

(DataContext as MSEntity).Refresh();

});

}

private Action GetIsEnabledAction()

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.IsEnabled)).ToList();

return new Action(() =>

{

selection.ForEach(item => item.entity.IsEnabled = item.IsEnabled);

(DataContext as MSEntity).Refresh();

});

}

private void OnName_TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

_propertyName = string.Empty;

_undoAction = GetRenameAction();

}

private void OnName_TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)

{

if (_propertyName == nameof(MSEntity.Name) && _undoAction != null)

{

var vm = DataContext as MSEntity;

var selection = vm.SelectedEntities.Select(entity => (entity, entity.Name)).ToList();

var redoAction = new Action(() =>

{

selection.ForEach(item => item.entity.Name = item.Name);

});

Project.UndoRedo.Add(new UndoRedoAction(_undoAction, redoAction, "Rename game entity"));

_propertyName = null;

};

_undoAction = null;

}

private void OnIsEnabled_CheckBox_Click(object sender, RoutedEventArgs e)

{

var undoAction = GetIsEnabledAction();

var vm = DataContext as MSEntity;

vm.IsEnabled = (sender as CheckBox).IsChecked == true;

var redoAction = GetIsEnabledAction();

Project.UndoRedo.Add(new UndoRedoAction(undoAction, redoAction,

vm.IsEnabled == true ? "Enable game entity" : "Disable game entity"

));

}

private void OnAddComponent_Button_PreviewMouse_LBD(object sender, MouseButtonEventArgs e)

{

var menu = FindResource("addComponentMenu") as ContextMenu;

var btn = sender as ToggleButton;

btn.IsChecked = true;

menu.Placement = PlacementMode.Bottom;

menu.PlacementTarget = btn;

menu.MinWidth = btn.ActualWidth;

menu.IsOpen = true;

}

private void AddComponent(ComponentType componentType, object data)

{

var creationFunction = ComponentFactory.GetCreationFunction(componentType);

var changedEntities = new List<(GameEntity entity, Component component)>();

var vm = DataContext as MSEntity;

foreach (var entity in vm.SelectedEntities)

{

var component = creationFunction(entity, data);

if (entity.AddComponent(component))

{

changedEntities.Add((entity, component));

}

}

if (changedEntities.Any())

{

vm.Refresh();

Project.UndoRedo.Add(new UndoRedoAction(

() =>

{

changedEntities.ForEach(x => x.entity.RemoveComponent(x.component));

(DataContext as MSEntity).Refresh();

},

() =>

{

changedEntities.ForEach(x => x.entity.AddComponent(x.component));

(DataContext as MSEntity).Refresh();

},

$"Add {componentType} component"

));

}

}

private void AddScriptComponent(object sender, RoutedEventArgs e)

{

AddComponent(ComponentType.Script, (sender as MenuItem).Header.ToString());

}

}

}

相关推荐
JosieBook8 小时前
【开源】一款开源、跨平台的.NET WPF 通用权限开发框架 (ABP) ,功能全面、界面美观
.net·wpf
你我约定有三9 小时前
分布式微服务--Nacos作为配置中心(二)
java·分布式·spring cloud·微服务·架构·wpf·负载均衡
界面开发小八哥12 小时前
界面组件DevExpress WPF中文教程:网格视图数据布局 - 数据单元格
.net·wpf·界面控件·devexpress·ui开发
EngZegNgi19 小时前
Unity —— Android 应用构建与发布
android·unity·自动化·游戏引擎·构建
向宇it20 小时前
【unity实战】简易的车辆控制系统
游戏·unity·c#·游戏引擎
三千道应用题1 天前
WPF&C#超市管理系统(4)入库管理
c#·wpf
freesheep7202 天前
WPF使用PreviewTextInput事件限制用户输入
c#·wpf
枫景Maple2 天前
Shader开发(六)什么是着色器
游戏引擎·着色器
向宇it2 天前
【unity小技巧】封装unity适合2D3D进行鼠标射线检测,获取鼠标位置信息检测工具类
游戏·3d·unity·游戏引擎
年少无知且疯狂2 天前
【Unity】实现小地图
unity·游戏引擎