mirror of
https://github.com/k1tbyte/Wand-Enhancer.git
synced 2026-08-29 01:08:51 +00:00
added runtime patcher, added MemoryUtils, fixes
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<UserControl x:Class="WeModPatcher.View.Controls.InfoItem"
|
||||
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:WeModPatcher.View.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Viewbox Width="20" Height="20" VerticalAlignment="Top">
|
||||
<Path Fill="{Binding IconColor}" Data="{Binding IconData}"/>
|
||||
</Viewbox>
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="5 0 5 0" TextWrapping="Wrap"
|
||||
FontSize="12" Text="{Binding Text}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WeModPatcher.View.Controls
|
||||
{
|
||||
public partial class InfoItem : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty IconDataProperty =
|
||||
DependencyProperty.Register(nameof(IconData), typeof(Geometry), typeof(InfoItem));
|
||||
|
||||
public static readonly DependencyProperty IconColorProperty =
|
||||
DependencyProperty.Register(nameof(IconColor), typeof(Brush), typeof(InfoItem));
|
||||
|
||||
public static readonly DependencyProperty TextProperty =
|
||||
DependencyProperty.Register(nameof(Text), typeof(string), typeof(InfoItem));
|
||||
|
||||
public Geometry IconData
|
||||
{
|
||||
get => (Geometry)GetValue(IconDataProperty);
|
||||
set => SetValue(IconDataProperty, value);
|
||||
}
|
||||
|
||||
public Brush IconColor
|
||||
{
|
||||
get => (Brush)GetValue(IconColorProperty);
|
||||
set => SetValue(IconColorProperty, value);
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => (string)GetValue(TextProperty);
|
||||
set => SetValue(TextProperty, value);
|
||||
}
|
||||
|
||||
public InfoItem()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,11 @@
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<TextBlock x:Name="Title" Text="This is title" Foreground="{DynamicResource Foreground}"
|
||||
HorizontalAlignment="Left" FontWeight="Bold" FontSize="16"
|
||||
VerticalAlignment="Bottom"/>
|
||||
<StackPanel Grid.Row="0" x:Name="TitleContainer" Orientation="Horizontal">
|
||||
<TextBlock x:Name="Title" Text="This is title" Foreground="{DynamicResource Foreground}"
|
||||
HorizontalAlignment="Left" FontWeight="Bold" FontSize="16"
|
||||
VerticalAlignment="Bottom"/>
|
||||
</StackPanel>
|
||||
|
||||
<ContentPresenter x:Name="Presenter" Margin="0 20 0 0"
|
||||
Content="{Binding PopupContent}" Grid.Row="2"/>
|
||||
|
||||
@@ -65,6 +65,10 @@ namespace WeModPatcher.View.Controls
|
||||
|
||||
Visibility = Visibility.Collapsed;
|
||||
Closed?.Invoke();
|
||||
if (PopupContent is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
PopupContent = null;
|
||||
Closed = null;
|
||||
OpenedSemaphore.Release();
|
||||
|
||||
@@ -88,14 +88,14 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Margin="10" Cursor="Hand" Background="Transparent">
|
||||
<Grid.InputBindings>
|
||||
<MouseBinding Gesture="LeftClick" Command="{Binding SetFolderPathCommand}" />
|
||||
</Grid.InputBindings>
|
||||
<TextBox Style="{StaticResource TitledTextBox}"
|
||||
Uid="Folder path" IsReadOnly="True"
|
||||
Text="{Binding WeModPath}"
|
||||
VerticalAlignment="Center" Tag="Folder not found">
|
||||
</TextBox>
|
||||
<Grid.InputBindings>
|
||||
<MouseBinding Gesture="LeftClick" Command="{Binding SetFolderPathCommand}" />
|
||||
</Grid.InputBindings>
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
@@ -11,16 +11,19 @@ namespace WeModPatcher.View.MainWindow
|
||||
public partial class MainWindow
|
||||
{
|
||||
public static MainWindow Instance;
|
||||
public readonly MainWindowVm ViewModel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = new MainWindowVm(this);
|
||||
this.ViewModel = new MainWindowVm(this);
|
||||
this.DataContext = ViewModel;
|
||||
VersionLabel.Text = Constants.Version.ToString();
|
||||
Instance = this;
|
||||
|
||||
}
|
||||
|
||||
public void OpenPopup(object content, string title = null)
|
||||
public void OpenPopup(FrameworkElement content, string title = null)
|
||||
{
|
||||
this.PopupHost.PopupContent = content;
|
||||
PopupHost.Title.Text = title;
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using AsarSharp;
|
||||
using WeModPatcher.ReactiveCore;
|
||||
using WeModPatcher.Core;
|
||||
using WeModPatcher.Models;
|
||||
using WeModPatcher.ReactiveUICore;
|
||||
using WeModPatcher.Utils;
|
||||
using WeModPatcher.View.Popups;
|
||||
using Application = System.Windows.Application;
|
||||
@@ -18,7 +21,7 @@ namespace WeModPatcher.View.MainWindow
|
||||
public class MainWindowVm : ObservableObject
|
||||
{
|
||||
private readonly MainWindow _view;
|
||||
public ObservableCollection<LogEntry> LogList { get; } = new ObservableCollection<LogEntry>();
|
||||
public ObservableCollection<LogEntry> LogList { get; set; } = new ObservableCollection<LogEntry>();
|
||||
private static Updater _updater = new Updater();
|
||||
|
||||
private string _weModPath;
|
||||
@@ -71,50 +74,6 @@ namespace WeModPatcher.View.MainWindow
|
||||
public RelayCommand RestoreBackupCommand { get; }
|
||||
public AsyncRelayCommand UpdateCommand { get; }
|
||||
|
||||
private static bool CheckWeModPath(string root)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.Exists(Path.Combine(root, "WeMod.exe")) &&
|
||||
File.Exists(Path.Combine(root, "resources", "app.asar"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string FindWeModDirectory()
|
||||
{
|
||||
string localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA");
|
||||
|
||||
string defaultDir = Path.Combine(localAppDataPath ?? "", "WeMod");
|
||||
|
||||
if (!Directory.Exists(defaultDir))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var appFolders = Directory.EnumerateDirectories(defaultDir)
|
||||
.Select(folderPath => new DirectoryInfo(folderPath))
|
||||
.Where(dirInfo => Regex.IsMatch(dirInfo.Name, @"^app-\w+"))
|
||||
.Select(dirInfo => new
|
||||
{
|
||||
Name = dirInfo.Name,
|
||||
Path = dirInfo.FullName,
|
||||
LastModified = dirInfo.LastWriteTime
|
||||
})
|
||||
.OrderByDescending(item => item.LastModified)
|
||||
.ToList();
|
||||
|
||||
return (
|
||||
from folder
|
||||
in appFolders
|
||||
where CheckWeModPath(folder.Path)
|
||||
select folder.Path
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
private void OnFolderPathSelection(object obj)
|
||||
{
|
||||
using (var dialog = new FolderBrowserDialog())
|
||||
@@ -127,7 +86,7 @@ namespace WeModPatcher.View.MainWindow
|
||||
string selectedPath = dialog.SelectedPath;
|
||||
string fileName = Path.GetFileName(selectedPath);
|
||||
|
||||
if (CheckWeModPath(selectedPath))
|
||||
if (Extensions.CheckWeModPath(selectedPath))
|
||||
{
|
||||
WeModPath = selectedPath;
|
||||
return;
|
||||
@@ -143,6 +102,7 @@ namespace WeModPatcher.View.MainWindow
|
||||
|
||||
private void OnBackupRestoring(object param)
|
||||
{
|
||||
|
||||
var backupPath = Path.Combine(WeModPath, "resources", "app.asar.backup");
|
||||
if (!File.Exists(backupPath))
|
||||
{
|
||||
@@ -155,6 +115,22 @@ namespace WeModPatcher.View.MainWindow
|
||||
using (File.Open(backupPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
|
||||
{
|
||||
}
|
||||
|
||||
// This shit doesn't look at the hash and verify() always returns true
|
||||
//using X509Certificate2 cert = new X509Certificate2(X509Certificate.CreateFromSignedFile(filePath));
|
||||
|
||||
var restoreExeResult = MemoryUtils.PatchFile( Path.Combine( WeModPath, "WeMod.exe"),
|
||||
Constants.ExePatchSignature, Constants.ExePatchSignature.OriginalBytes);
|
||||
if (restoreExeResult == -1)
|
||||
{
|
||||
Log("Failed to restore the backup. Please close the WeMod and try again.", ELogType.Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(restoreExeResult == 0 ?
|
||||
"Signature exe is original, does not require restoration"
|
||||
: "WeMod.exe restored successfully", ELogType.Success);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -177,12 +153,24 @@ namespace WeModPatcher.View.MainWindow
|
||||
return;
|
||||
}
|
||||
|
||||
MainWindow.Instance.OpenPopup(new PatchVectorsPopup(async config =>
|
||||
MainWindow.Instance.OpenPopup(new PatchVectorsPopup( async config =>
|
||||
{
|
||||
MainWindow.Instance.ClosePopup();
|
||||
IsPatchEnabled = false;
|
||||
await Task.Run(() => new Patcher(WeModPath, Log, config).Patch());
|
||||
IsPatchEnabled = true;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
new StaticPatcher(WeModPath, Log, config).Patch();
|
||||
AlreadyPatched = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to patch: {e.Message}", ELogType.Error);
|
||||
IsPatchEnabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
}), "What are we gonna patch?");
|
||||
}
|
||||
|
||||
@@ -229,7 +217,7 @@ namespace WeModPatcher.View.MainWindow
|
||||
RestoreBackupCommand = new RelayCommand(OnBackupRestoring);
|
||||
UpdateCommand = new AsyncRelayCommand(OnUpdate);
|
||||
|
||||
WeModPath = FindWeModDirectory();
|
||||
WeModPath = Extensions.FindWeModDirectory();
|
||||
if (WeModPath == null)
|
||||
{
|
||||
Log("WeMod directory not found.", ELogType.Error);
|
||||
|
||||
@@ -4,28 +4,123 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:WeModPatcher.View.Popups"
|
||||
xmlns:controls="clr-namespace:WeModPatcher.View.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300"
|
||||
d:DesignHeight="Auto" d:DesignWidth="Auto"
|
||||
Background="{DynamicResource Background}"
|
||||
Foreground="{DynamicResource MutedForeground}"
|
||||
FontWeight="Medium"
|
||||
FontSize="13">
|
||||
<Grid Margin="0 0 5 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" VerticalAlignment="Center" Text="Activate WeMod Pro"/>
|
||||
<CheckBox Grid.Row="0" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center" IsChecked="True"/>
|
||||
<UserControl.Resources>
|
||||
<Button x:Key="BackButton" Click="BackClicked" VerticalAlignment="Bottom" Padding="3"
|
||||
Margin="0 0 15 0"
|
||||
Width="35" Height="23" Style="{StaticResource IconButton}"
|
||||
Tag="{StaticResource ArrowLeft}"/>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid x:Name="PatchVectors" Visibility="Visible" Margin="0 0 5 0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="27"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" VerticalAlignment="Center" Text="Activate WeMod Pro"/>
|
||||
<CheckBox Grid.Row="0" x:Name="ActivateProBox" HorizontalAlignment="Right" VerticalAlignment="Center" IsChecked="True"/>
|
||||
|
||||
<TextBlock Grid.Row="1" VerticalAlignment="Center" Text="Disable telemetry"/>
|
||||
<CheckBox Grid.Row="1" x:Name="DisableTelemetryBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Row="1" VerticalAlignment="Center" Text="Disable telemetry"/>
|
||||
<CheckBox Grid.Row="1" x:Name="DisableTelemetryBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
|
||||
<TextBlock Grid.Row="2" VerticalAlignment="Center" Text="Disable updates"/>
|
||||
<CheckBox Grid.Row="2" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Row="2" VerticalAlignment="Center" Text="Disable updates"/>
|
||||
<CheckBox Grid.Row="2" x:Name="DisableUpdateBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
|
||||
<Button Grid.Row="3" Padding="0 5 0 5" Margin="0 15 0 0" Content="Continue"
|
||||
Click="ButtonBase_OnClick"/>
|
||||
<Button Grid.Row="3" Padding="0 5 0 5" Margin="0 15 0 0" Content="Continue"
|
||||
Click="NextClicked"/>
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="PatchMethod" Visibility="Collapsed" Width="650">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="250"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid>
|
||||
<Border Background="{DynamicResource Muted}" HorizontalAlignment="Right" Width="2"
|
||||
CornerRadius="10"/>
|
||||
<StackPanel>
|
||||
<TextBlock FontSize="16" Text="Static" Foreground="{DynamicResource Foreground}" HorizontalAlignment="Center" Margin="0 0 0 10"/>
|
||||
<controls:InfoItem
|
||||
IconColor="SpringGreen"
|
||||
IconData="{StaticResource CheckDecagram}"
|
||||
Text="Starting WeMod without this program" />
|
||||
|
||||
<controls:InfoItem
|
||||
Margin="0 15 0 0"
|
||||
IconColor="PaleVioletRed"
|
||||
IconData="{StaticResource AlertDecagram}"
|
||||
Text="Violation of WeMod digital signature (possibly marked by antiviruses, anti-cheats)" />
|
||||
|
||||
<controls:InfoItem
|
||||
Margin="0 10 0 0"
|
||||
IconColor="PaleVioletRed"
|
||||
IconData="{StaticResource AlertDecagram}"
|
||||
Text="Auto-patching after WeMod updates is not available" />
|
||||
|
||||
<controls:InfoItem
|
||||
Margin="0 10 0 0"
|
||||
IconColor="PaleVioletRed"
|
||||
IconData="{StaticResource AlertDecagram}"
|
||||
Text="Hotkeys will be broken" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid Grid.Row="0" Grid.Column="1">
|
||||
<StackPanel Margin="10 0 0 0">
|
||||
<TextBlock FontSize="16" Text="Runtime" Foreground="{DynamicResource Foreground}"
|
||||
HorizontalAlignment="Center" Margin="-10 0 0 10"/>
|
||||
|
||||
<controls:InfoItem
|
||||
IconColor="SpringGreen"
|
||||
IconData="{StaticResource CheckDecagram}"
|
||||
Text="Hotkeys still work" />
|
||||
|
||||
<controls:InfoItem Margin="0 10 0 0"
|
||||
IconColor="SpringGreen"
|
||||
IconData="{StaticResource CheckDecagram}"
|
||||
Text="Does not break the digital signature (does not make changes to the original .exe)" />
|
||||
|
||||
<controls:InfoItem Margin="0 10 0 0"
|
||||
IconColor="SpringGreen"
|
||||
IconData="{StaticResource CheckDecagram}"
|
||||
Text="Automatically applies patches to new versions (referring to your current selection)" />
|
||||
|
||||
<controls:InfoItem
|
||||
Margin="0 10 0 0"
|
||||
IconColor="Yellow"
|
||||
IconData="{StaticResource AlertDecagram}"
|
||||
Text="The WeMod startup process is controlled by the patcher. (Don't worry, you will no longer see this window. You will run WeMod as usual but using the shortcut that will be created after choosing this method). So you will want to keep this program. Make sure it's in a safe directory (not Temp, Downloads, etc)." />
|
||||
|
||||
<controls:InfoItem Margin="0 10 0 0"
|
||||
IconColor="PaleVioletRed"
|
||||
IconData="{StaticResource AlertDecagram}"
|
||||
Text="Running WeMod directly through official WeMod.exe is not possible until you restore patch backup" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Button Grid.Column="0" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Center"
|
||||
Padding="10 5" Margin="0 15 0 0"
|
||||
Click="OnStaticSelected"
|
||||
Content="Use static"/>
|
||||
|
||||
<Button Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Center"
|
||||
Padding="10 5" Margin="0 15 0 0"
|
||||
Click="OnRuntimeSelected"
|
||||
Content="Use runtime"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
|
||||
@@ -3,22 +3,42 @@ using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using WeModPatcher.Models;
|
||||
using WeModPatcher.View.Controls;
|
||||
|
||||
namespace WeModPatcher.View.Popups
|
||||
{
|
||||
public partial class PatchVectorsPopup : UserControl
|
||||
public partial class PatchVectorsPopup : UserControl, IDisposable
|
||||
{
|
||||
private readonly Action<HashSet<EPatchType>> _onApply;
|
||||
private readonly Action<PatchConfig> _onApply;
|
||||
private readonly StackPanel _popupTitleContainer;
|
||||
private string _originalTitle;
|
||||
private readonly TextBlock _titleTextBlock;
|
||||
|
||||
public PatchVectorsPopup(Action<HashSet<EPatchType>> onApply)
|
||||
public PatchVectorsPopup(Action<PatchConfig> onApply)
|
||||
{
|
||||
_onApply = onApply;
|
||||
InitializeComponent();
|
||||
_popupTitleContainer = MainWindow.MainWindow.Instance.PopupHost.TitleContainer;
|
||||
_titleTextBlock = _popupTitleContainer.Children[0] as TextBlock;
|
||||
}
|
||||
|
||||
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||
|
||||
private void BackClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if(ActivateProBox.IsChecked != true && DisableUpdateBox.IsChecked != true && DisableTelemetryBox.IsChecked != true)
|
||||
Dispose();
|
||||
PatchMethod.Visibility = Visibility.Collapsed;
|
||||
PatchVectors.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void OnRuntimeSelected(object sender, RoutedEventArgs e)
|
||||
=> RaiseCallback(EPatchProcessMethod.Runtime);
|
||||
|
||||
private void OnStaticSelected(object sender, RoutedEventArgs e)
|
||||
=> RaiseCallback(EPatchProcessMethod.Static);
|
||||
|
||||
private void RaiseCallback(EPatchProcessMethod method)
|
||||
{
|
||||
if (ActivateProBox.IsChecked != true && DisableUpdateBox.IsChecked != true &&
|
||||
DisableTelemetryBox.IsChecked != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -28,13 +48,35 @@ namespace WeModPatcher.View.Popups
|
||||
{
|
||||
result.Add(EPatchType.ActivatePro);
|
||||
}
|
||||
|
||||
|
||||
if (DisableUpdateBox.IsChecked == true)
|
||||
{
|
||||
result.Add(EPatchType.DisableUpdates);
|
||||
}
|
||||
|
||||
_onApply(result);
|
||||
|
||||
_onApply(new PatchConfig
|
||||
{
|
||||
PatchTypes = result,
|
||||
PatchMethod = method
|
||||
});
|
||||
}
|
||||
|
||||
private void NextClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_popupTitleContainer.Children.Insert(0, FindResource("BackButton") as Button);
|
||||
_originalTitle = _titleTextBlock.Text;
|
||||
_titleTextBlock.Text = "Patch method";
|
||||
PatchMethod.Visibility = Visibility.Visible;
|
||||
PatchVectors.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (PatchVectors.Visibility == Visibility.Collapsed)
|
||||
{
|
||||
_popupTitleContainer.Children.RemoveAt(0);
|
||||
_titleTextBlock.Text = _originalTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user