1
0

feat: support view model closing view window

This commit is contained in:
2026-04-05 18:07:15 +08:00
parent a55a8c7456
commit a9fab50ada
27 changed files with 501 additions and 153 deletions

View File

@@ -17,13 +17,11 @@
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<PackageReference Include="DotNetZip" Version="1.9.1.8" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.142" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="10.0.5" />
</ItemGroup>
<ItemGroup>
<Folder Include="Frontend\Models\" />
<Folder Include="Frontend\Utils\" />
</ItemGroup>
</Project>

View File

@@ -1,49 +0,0 @@
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BallanceTasEditor.Frontend.Behaviors {
public class ConfirmCloseBehavior : Behavior<Window> {
public ICommand ConfirmCommand {
get { return (ICommand)GetValue(ConfirmCommandProperty); }
set { SetValue(ConfirmCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for ConfirmCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ConfirmCommandProperty =
DependencyProperty.Register("ConfirmCommand", typeof(ICommand), typeof(ConfirmCloseBehavior));
protected override void OnAttached() {
base.OnAttached();
AssociatedObject.Closing += OnClosing;
}
protected override void OnDetaching() {
AssociatedObject.Closing -= OnClosing;
base.OnDetaching();
}
private void OnClosing(object? sender, CancelEventArgs e) {
if (ConfirmCommand?.CanExecute(null) == true) {
// 假设Command返回 bool 或通过回调/事件通知结果
bool allowClose = (Func<object?, bool>)ConfirmCommand.Execute(null);
e.Cancel = !allowClose;
}
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.Shared {
public static class BrowserHelper {
public static void OpenInDefaultBrowser(string url) {
if (string.IsNullOrWhiteSpace(url)) {
throw new ArgumentException("The content of URL should not be empty.", nameof(url));
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
// Windows 必须设置 UseShellExecute = true 才能识别 URL
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
Process.Start("xdg-open", url);
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
Process.Start("open", url);
} else {
throw new PlatformNotSupportedException("Not supported operating system.");
}
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.Shared {
public static class Constant {
public const string REPORT_BUG_URL = "https://github.com/yyc12345/BallanceTasToolbox/issues";
// YYC MARK:
// TAS usually used FPS is 132 or 264.
public const uint DEFAULT_FPS = 264;
public const uint DEFAULT_NEW_COUNT = 10000;
public const uint DEFAULT_INSERT_COUNT = 100;
}
}

View File

@@ -5,33 +5,71 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace BallanceTasEditor.Frontend.Views {
namespace BallanceTasEditor.Frontend.Shared {
public class DialogService : ViewModels.IDialogService {
public interface IDialogService {
NewFileDialogResult? ShowNewFileDialog();
OpenFileDialogResult? ShowOpenFileDialog();
void ShowOpenFileFailedDialog(Exception e);
SaveFileDialogResult? ShowSaveFileDialog();
void ShowSaveFileFailedDialog(Exception e);
bool ShowConfirmCloseFileDialog(string message);
bool ShowConfirmExitWhenOpeningFileDialog();
bool ShowFileChangedDialog();
GotoDialogResult? ShowGotoDialog();
EditFpsDialogResult? ShowEditFpsDialog();
AddFrameDialogResult? ShowAddFrameDialog();
PreferenceDialogResult? ShowPreferenceDialog();
void ShowManuallyReportBugDialog();
void ShowAboutDialog();
}
public record NewFileDialogResult {
public required uint Fps { get; init; }
public required int Count { get; init; }
}
public record OpenFileDialogResult {
public required string Path { get; init; }
}
public record SaveFileDialogResult {
public required string Path { get; init; }
}
public record GotoDialogResult { }
public record EditFpsDialogResult { }
public record AddFrameDialogResult { }
public record PreferenceDialogResult { }
public class DialogService : IDialogService {
public DialogService(Window parent) {
m_Parent = parent;
}
private readonly Window m_Parent;
public ViewModels.NewFileDialogResult? ShowNewFileDialog() {
var dialog = new NewFileDialog();
public NewFileDialogResult? ShowNewFileDialog() {
var dialog = new Views.NewFileDialog();
dialog.Owner = m_Parent;
if (dialog.ShowDialog() is true) {
// TODO: Finish result extraction
return new ViewModels.NewFileDialogResult() { Count = 0, Fps = 60 };
return new NewFileDialogResult() { Count = 0, Fps = 60 };
} else {
return null;
}
}
public ViewModels.OpenFileDialogResult? ShowOpenFileDialog() {
public OpenFileDialogResult? ShowOpenFileDialog() {
Microsoft.Win32.OpenFileDialog op = new Microsoft.Win32.OpenFileDialog();
op.RestoreDirectory = true;
op.Multiselect = false;
op.Filter = "TAS file(*.tas)|*.tas|All file(*.*)|*.*";
if (op.ShowDialog() is true) {
return new ViewModels.OpenFileDialogResult() { Path = op.FileName };
return new OpenFileDialogResult() { Path = op.FileName };
} else {
return null;
}
@@ -43,12 +81,12 @@ namespace BallanceTasEditor.Frontend.Views {
MessageBoxButton.OK, MessageBoxImage.Error);
}
public ViewModels.SaveFileDialogResult? ShowSaveFileDialog() {
public SaveFileDialogResult? ShowSaveFileDialog() {
Microsoft.Win32.SaveFileDialog op = new Microsoft.Win32.SaveFileDialog();
op.RestoreDirectory = true;
op.Filter = "TAS file(*.tas)|*.tas|All file(*.*)|*.*";
if (op.ShowDialog() is true) {
return new ViewModels.SaveFileDialogResult() { Path = op.FileName };
return new SaveFileDialogResult() { Path = op.FileName };
} else {
return null;
}
@@ -85,55 +123,62 @@ namespace BallanceTasEditor.Frontend.Views {
return rv == MessageBoxResult.Yes;
}
public ViewModels.GotoDialogResult? ShowGotoDialog() {
var dialog = new GotoDialog();
public GotoDialogResult? ShowGotoDialog() {
var dialog = new Views.GotoDialog();
dialog.Owner = m_Parent;
if (dialog.ShowDialog() is true) {
// TODO: Finish result extraction
return new ViewModels.GotoDialogResult();
return new GotoDialogResult();
} else {
return null;
}
}
public ViewModels.EditFpsDialogResult? ShowEditFpsDialog() {
var dialog = new EditFpsDialog();
public EditFpsDialogResult? ShowEditFpsDialog() {
var dialog = new Views.EditFpsDialog();
dialog.Owner = m_Parent;
if (dialog.ShowDialog() is true) {
// TODO: Finish result extraction
return new ViewModels.EditFpsDialogResult();
return new EditFpsDialogResult();
} else {
return null;
}
}
public ViewModels.AddFrameDialogResult? ShowAddFrameDialog() {
var dialog = new AddFrameDialog();
public AddFrameDialogResult? ShowAddFrameDialog() {
var dialog = new Views.AddFrameDialog();
dialog.Owner = m_Parent;
if (dialog.ShowDialog() is true) {
// TODO: Finish result extraction
return new ViewModels.AddFrameDialogResult();
return new AddFrameDialogResult();
} else {
return null;
}
}
public ViewModels.PreferenceDialogResult? ShowPreferenceDialog() {
var dialog = new PreferenceDialog();
public PreferenceDialogResult? ShowPreferenceDialog() {
var dialog = new Views.PreferenceDialog();
dialog.Owner = m_Parent;
if (dialog.ShowDialog() is true) {
// TODO: Finish result extraction
return new ViewModels.PreferenceDialogResult();
return new PreferenceDialogResult();
} else {
return null;
}
}
public void ShowManuallyReportBugDialog() {
MessageBox.Show($"We can not open browser automatically for you. Please visit {Shared.Constant.REPORT_BUG_URL} manually to report bug.",
"Can not Open Browser",
MessageBoxButton.OK, MessageBoxImage.Information);
}
public void ShowAboutDialog() {
var dialog = new AboutDialog();
var dialog = new Views.AboutDialog();
dialog.Owner = m_Parent;
dialog.ShowDialog();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.Shared {
/// <summary>
/// The delegate used for view model requesting closing view window (non-modal window).
/// </summary>
public delegate void RequestCloseWindowEventHandler();
/// <summary>
/// The delegate used for view model requesting closing view dialog (modal window).
/// </summary>
public delegate void RequestCloseDialogEventHandler(RequestCloseDialogEventArgs e);
/// <summary>
/// The payload passed when requesting closing view dialog (modal window).
/// </summary>
public record RequestCloseDialogEventArgs {
/// <summary>
/// True if we want to close windows by clicking Ok button, otherwise false.
/// </summary>
public required bool Result { get; init; }
}
}

View File

@@ -0,0 +1,26 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class AboutDialog : ObservableObject {
public AboutDialog() { }
[RelayCommand]
private void Ok() {
OnRequestCloseDialog(true);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
}
}
}

View File

@@ -0,0 +1,46 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class AddFrameDialog : ObservableObject {
public AddFrameDialog() {
Count = Shared.Constant.DEFAULT_INSERT_COUNT.ToString();
Fps = Shared.Constant.DEFAULT_FPS.ToString();
}
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
OnRequestCloseDialog(true);
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string count;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string fps;
private bool CanOk() {
// TODO
return true;
}
[RelayCommand]
private void Cancel() {
OnRequestCloseDialog(false);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
}
}
}

View File

@@ -0,0 +1,42 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class EditFpsDialog : ObservableObject {
public EditFpsDialog() {
Fps = Shared.Constant.DEFAULT_FPS.ToString();
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string fps;
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
OnRequestCloseDialog(true);
}
private bool CanOk() {
// TODO
return true;
}
[RelayCommand]
private void Cancel() {
OnRequestCloseDialog(false);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
}
}
}

View File

@@ -0,0 +1,42 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class GotoDialog : ObservableObject {
public GotoDialog() {
Index = 0.ToString();
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string index;
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
OnRequestCloseDialog(true);
}
private bool CanOk() {
// TODO
return true;
}
[RelayCommand]
private void Cancel() {
OnRequestCloseDialog(false);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
}
}
}

View File

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public interface IDialogService {
NewFileDialogResult? ShowNewFileDialog();
OpenFileDialogResult? ShowOpenFileDialog();
void ShowOpenFileFailedDialog(Exception e);
SaveFileDialogResult? ShowSaveFileDialog();
void ShowSaveFileFailedDialog(Exception e);
bool ShowConfirmCloseFileDialog(string message);
bool ShowConfirmExitWhenOpeningFileDialog();
bool ShowFileChangedDialog();
GotoDialogResult? ShowGotoDialog();
EditFpsDialogResult? ShowEditFpsDialog();
AddFrameDialogResult? ShowAddFrameDialog();
PreferenceDialogResult? ShowPreferenceDialog();
void ShowAboutDialog();
}
public record NewFileDialogResult {
public required uint Fps { get; init; }
public required int Count { get; init; }
}
public record OpenFileDialogResult {
public required string Path { get; init; }
}
public record SaveFileDialogResult {
public required string Path { get; init; }
}
public record GotoDialogResult { }
public record EditFpsDialogResult { }
public record AddFrameDialogResult { }
public record PreferenceDialogResult { }
}

View File

@@ -2,20 +2,23 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class MainWindow : ObservableObject {
public MainWindow(IDialogService dialogService) {
public MainWindow(Shared.IDialogService dialogService) {
m_DialogService = dialogService;
this.TasFile = null;
this.TasFilePath = null;
}
private IDialogService m_DialogService;
private Shared.IDialogService m_DialogService;
#region File Operation
@@ -134,6 +137,40 @@ namespace BallanceTasEditor.Frontend.ViewModels {
#endregion
#region Exit Stuff
[RelayCommand]
private void Exit() {
// TODO
OnRequestCloseWindow();
}
public event Shared.RequestCloseWindowEventHandler? RequestCloseWindow;
private void OnRequestCloseWindow() {
RequestCloseWindow?.Invoke();
}
#endregion
#region Help Menu
[RelayCommand]
private void ReportBug() {
try {
Shared.BrowserHelper.OpenInDefaultBrowser(Shared.Constant.REPORT_BUG_URL);
} catch (Exception) {
m_DialogService.ShowManuallyReportBugDialog();
}
}
[RelayCommand]
private void About() {
m_DialogService.ShowAboutDialog();
}
#endregion
#region UI Only
public string WindowTitle {

View File

@@ -9,11 +9,10 @@ using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class NewFileDialog : ObservableValidator {
public partial class NewFileDialog : ObservableObject {
public NewFileDialog() {
Count = 10000.ToString();
// 132 or 264
Fps = 264.ToString();
Count = Shared.Constant.DEFAULT_NEW_COUNT.ToString();
Fps = Shared.Constant.DEFAULT_FPS.ToString();
}
// YYC MARK:
@@ -39,33 +38,49 @@ namespace BallanceTasEditor.Frontend.ViewModels {
// 就直接把string绑定到TextBox.Text上然后再辅以我自己定义的一套可复用验证逻辑。
[ObservableProperty]
//[CustomValidation(typeof(NewFileDialog), nameof(ValidateCount))]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string count;
[ObservableProperty]
//[CustomValidation(typeof(NewFileDialog), nameof(ValidateFps))]
[NotifyCanExecuteChangedFor(nameof(OkCommand))]
private string fps;
//public static ValidationResult ValidateCount(string count, ValidationContext context) {
// return CountValidator.Instance.Validate(count);
//}
//public static ValidationResult ValidateFps(string fps, ValidationContext context) {
// return FpsValidator.Instance.Validate(fps);
//}
//[ObservableProperty]
////[CustomValidation(typeof(NewFileDialog), nameof(ValidateCount))]
//[NotifyCanExecuteChangedFor(nameof(OkCommand))]
//private string count;
//[ObservableProperty]
////[CustomValidation(typeof(NewFileDialog), nameof(ValidateFps))]
//[NotifyCanExecuteChangedFor(nameof(OkCommand))]
//private string fps;
////public static ValidationResult ValidateCount(string count, ValidationContext context) {
//// return CountValidator.Instance.Validate(count);
////}
////public static ValidationResult ValidateFps(string fps, ValidationContext context) {
//// return FpsValidator.Instance.Validate(fps);
////}
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
OnRequestCloseDialog(true);
}
private bool CanOk() {
return !HasErrors;
// TODO
return true;
}
[RelayCommand]
private void Cancel() {
OnRequestCloseDialog(false);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result});
}
//public NewFileDialogResult ToResult() {

View File

@@ -0,0 +1,40 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BallanceTasEditor.Frontend.ViewModels {
public partial class PreferenceDialog : ObservableObject {
public PreferenceDialog() {
}
[RelayCommand(CanExecute = nameof(CanOk))]
private void Ok() {
OnRequestCloseDialog(true);
}
private bool CanOk() {
// TODO
return true;
}
[RelayCommand]
private void Cancel() {
OnRequestCloseDialog(false);
}
public event Shared.RequestCloseDialogEventHandler? RequestCloseDialog;
private void OnRequestCloseDialog(bool result) {
RequestCloseDialog?.Invoke(new Shared.RequestCloseDialogEventArgs { Result = result });
}
}
}

View File

@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
d:DataContext="{d:DesignInstance vm:AboutDialog}"
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
Title="About Ballance TAS Editor" Width="340" Height="480" Icon="/Frontend/Assets/About.ico">
<Grid>
@@ -24,7 +26,7 @@
<!-- 详情(版权信息等) -->
<TextBox Grid.Row="3" IsReadOnly="True" TextWrapping="Wrap" Margin="10"
ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Text="Copyright © 2021-2025 yyc12345. All rights reserved.&#13;
Text="Copyright © 2021-2026 yyc12345. All rights reserved.&#13;
&#13;
Program: yyc12345 &#13;
Icon design: plAer_2 &#13;
@@ -33,6 +35,6 @@ Version: 1.2 stable&#13;
Build Date: October 21, 2025&#13;"/>
<!-- 确认按钮 -->
<Button Grid.Row="4" Content="OK" Margin="10" HorizontalAlignment="Center" Style="{StaticResource OkButtonStyle}" IsDefault="True"/>
<Button Grid.Row="4" Content="OK" Margin="10" HorizontalAlignment="Center" Style="{StaticResource OkButtonStyle}" IsDefault="True" Command="{Binding OkCommand}"/>
</Grid>
</Window>

View File

@@ -19,6 +19,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class AboutDialog : Window {
public AboutDialog() {
InitializeComponent();
var vm = new ViewModels.AboutDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}

View File

@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
d:DataContext="{d:DesignInstance vm:AddFrameDialog}"
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
Title="Add Frame" Height="250" Width="400" Icon="/Frontend/Assets/AddFrame.ico">
<Grid>
@@ -51,8 +53,10 @@
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right" Margin="10">
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"/>
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"
Command="{Binding OkCommand}"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"
Command="{Binding CancelCommand}"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -19,6 +19,14 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class AddFrameDialog : Window {
public AddFrameDialog() {
InitializeComponent();
var vm = new ViewModels.AddFrameDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}

View File

@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
d:DataContext="{d:DesignInstance vm:EditFpsDialog}"
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
Title="Edit FPS" Height="220" Width="400" Icon="/Frontend/Assets/SetFps.ico">
<Grid>
@@ -46,8 +48,10 @@
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right" Margin="10">
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"/>
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"
Command="{Binding OkCommand}"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"
Command="{Binding CancelCommand}"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -19,6 +19,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class EditFpsDialog : Window {
public EditFpsDialog() {
InitializeComponent();
var vm = new ViewModels.EditFpsDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}

View File

@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
d:DataContext="{d:DesignInstance vm:GotoDialog}"
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
Title="Goto..." Height="180" Width="400" Icon="/Frontend/Assets/Goto.ico">
<Grid>
@@ -26,8 +28,10 @@
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2" HorizontalAlignment="Right" Margin="10">
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"/>
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"
Command="{Binding OkCommand}"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"
Command="{Binding CancelCommand}"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -19,6 +19,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class GotoDialog : Window {
public GotoDialog() {
InitializeComponent();
var vm = new ViewModels.GotoDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}

View File

@@ -55,7 +55,7 @@
<MenuItem Header="Save File then _Run Game" Icon="{StaticResource IconSaveFileThenRunGame}" InputGestureText="B"/>
<Separator/>
<MenuItem Header="Close File" Icon="{StaticResource IconCloseFile}" Command="{Binding CloseFileCommand}"/>
<MenuItem Header="Exit" Icon="{StaticResource IconExit}"/>
<MenuItem Header="Exit" Icon="{StaticResource IconExit}" Command="{Binding ExitCommand}"/>
</MenuItem>
<MenuItem Header="_Edit" Padding="5">
<MenuItem Header="_Undo" Icon="{StaticResource IconUndo}" InputGestureText="Ctrl+Z"/>
@@ -77,8 +77,8 @@
<MenuItem Header="Preference" Icon="{StaticResource IconPreference}" InputGestureText="Ctrl+P"/>
</MenuItem>
<MenuItem Header="_Help" Padding="5">
<MenuItem Header="Report Bug" Icon="{StaticResource IconReportBug}"/>
<MenuItem Header="About" Icon="{StaticResource IconAbout}"/>
<MenuItem Header="Report Bug" Icon="{StaticResource IconReportBug}" Command="{Binding ReportBugCommand}"/>
<MenuItem Header="About" Icon="{StaticResource IconAbout}" Command="{Binding AboutCommand}"/>
</MenuItem>
</Menu>

View File

@@ -20,9 +20,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
var dialogService = new DialogService(this);
this.DataContext = new ViewModels.MainWindow(dialogService);
var dialogService = new Shared.DialogService(this);
var vm = new ViewModels.MainWindow(dialogService);
vm.RequestCloseWindow += ViewModel_RequestCloseWindow;
this.DataContext = vm;
}
private void ViewModel_RequestCloseWindow() {
this.Close();
}
}
}

View File

@@ -19,7 +19,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class NewFileDialog : Window {
public NewFileDialog() {
InitializeComponent();
this.DataContext = new ViewModels.NewFileDialog();
var vm = new ViewModels.NewFileDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}

View File

@@ -4,7 +4,9 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallanceTasEditor.Frontend.Views"
xmlns:vm="clr-namespace:BallanceTasEditor.Frontend.ViewModels"
xmlns:styles="clr-namespace:BallanceTasEditor.Frontend.Styles"
d:DataContext="{d:DesignInstance vm:PreferenceDialog}"
mc:Ignorable="d" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False"
Title="Editor Preference" Height="450" Width="400" Icon="/Frontend/Assets/Preference.ico">
<Grid>
@@ -57,8 +59,10 @@
</ScrollViewer>
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right" Margin="10">
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"/>
<Button Content="OK" Margin="5" Style="{StaticResource OkButtonStyle}" IsDefault="True"
Command="{Binding OkCommand}"/>
<Button Content="Cancel" Margin="5" Style="{StaticResource CancelButtonStyle}"
Command="{Binding CancelCommand}"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -19,6 +19,15 @@ namespace BallanceTasEditor.Frontend.Views {
public partial class PreferenceDialog : Window {
public PreferenceDialog() {
InitializeComponent();
var vm = new ViewModels.PreferenceDialog();
vm.RequestCloseDialog += ViewModel_RequestCloseDialog;
this.DataContext = vm;
}
private void ViewModel_RequestCloseDialog(Shared.RequestCloseDialogEventArgs e) {
this.DialogResult = e.Result;
this.Close();
}
}
}