Answer the question
In order to leave comments, you need to log in
How to move the button method to a separate class in WPF?
There are buttons, depending on the state of the button, different methods are called. What the methods do is described in the MainWindow.cs class. These methods make the label animation. Since I have a lot of animation planned, I would like to store all the animation of the elements in a separate class, for example, in Animation.cs
That is, you just need to transfer the methods from the Mainwindow.cs class to Animation.cs
How to do this?
MainWindow.xaml:
<RadioButton x:Name="CategoryToggle1"
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource RadioButton}"
GroupName="ToggleButtonsGroup"
Checked="OpenOptions"
Unchecked="HideOptions" />
<RadioButton x:Name="CategoryToggle2"
Grid.Row="3"
Grid.Column="1"
Style="{StaticResource RadioButton}"
GroupName="ToggleButtonsGroup"
Checked="OpenOptions"
Unchecked="HideOptions">
namespace Toolkits
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
bool isOptionsOpen1 = false;
bool isOptionsOpen2 = false;
public MainWindow()
{
InitializeComponent();
HotKeys hk = new HotKeys(this);
Animation animation = new Animation(this);
}
private void OpenOptions(object sender, RoutedEventArgs e)
{
RadioButton radioButton = sender as RadioButton;
radioButton.IsChecked = true;
//Disable all option buttons except one that active
MyGrid.Children.OfType<RadioButton>().Where(rb => rb != radioButton && rb.GroupName == radioButton.GroupName).ToList().ForEach(rb => rb.IsEnabled = false);
if(CategoryToggle1.IsChecked == true)
{
CategoryLabel1.Content = "Category 1 is Checked";
}
if (CategoryToggle2.IsChecked == true)
{
CategoryLabel2.Content = "Category 2 is Checked";
}
var sb = new Storyboard();
var ta = new ThicknessAnimation();
ta.BeginTime = new TimeSpan(0);
if (CategoryToggle1.IsChecked == true)
{
isOptionsOpen1 = true;
ta.SetValue(Storyboard.TargetNameProperty, "RectCategory1");
}
if (CategoryToggle2.IsEnabled == true)
{
isOptionsOpen2 = true;
ta.SetValue(Storyboard.TargetNameProperty, "RectCategory2");
}
Storyboard.SetTargetProperty(ta, new PropertyPath(MarginProperty));
ta.From = new Thickness(0, 0, 0, 0);
ta.To = new Thickness((RectCategory1.ActualWidth /100) * 20, 0, 0, 0);
ta.Duration = new Duration(TimeSpan.FromSeconds(0.3));
sb.Children.Add(ta);
sb.Begin(this);
}
private void HideOptions(object sender, RoutedEventArgs e)
{
RadioButton radioButton = sender as RadioButton;
MyGrid.Children.OfType<RadioButton>().Where(rb => rb.GroupName == radioButton.GroupName).ToList().ForEach(rb => rb.IsEnabled = true);
if (CategoryToggle1.IsChecked == false)
{
CategoryLabel1.Content = "Category 1 is UNCHECKED";
}
if (CategoryToggle2.IsChecked == false)
{
CategoryLabel2.Content = "Category 2 is UNCHECKED";
}
var sb = new Storyboard();
var ta = new ThicknessAnimation();
ta.BeginTime = new TimeSpan(0);
if (isOptionsOpen1 == true)
{
ta.SetValue(Storyboard.TargetNameProperty, "RectCategory1");
}
if (isOptionsOpen2 == true)
{
ta.SetValue(Storyboard.TargetNameProperty, "RectCategory2");
}
Storyboard.SetTargetProperty(ta, new PropertyPath(MarginProperty));
ta.From = new Thickness((RectCategory1.ActualWidth / 100) * 20, 0, 0, 0);
ta.To = new Thickness(0, 0, 0, 0);
ta.Duration = new Duration(TimeSpan.FromSeconds(0.3));
sb.Children.Add(ta);
sb.Begin(this);
isOptionsOpen1 = false;
isOptionsOpen2 = false;
}
}
}
Answer the question
In order to leave comments, you need to log in
You don't need to wrap methods. Just describe them in the class you need and call them in methods in the window class.
For example like this:
public partial class MainWindow : Window
{
Animation animation;
bool isOptionsOpen1 = false;
bool isOptionsOpen2 = false;
public MainWindow()
{
InitializeComponent();
HotKeys hk = new HotKeys(this);
animation = new Animation(this);
}
private void OpenOptions(object sender, RoutedEventArgs e)
{
animation.OpenOptions();
}
private void HideOptions(object sender, RoutedEventArgs e)
{
animation.HideOptions();
}
}
Learn the MVVM pattern and use it.
Example:
The code was taken from a combat solution. If it's not clear, ask
public partial class SetColdBalance : Window
{
public SetColdBalance()
{
InitializeComponent();
}
}
public class RelayCommand<T> : ICommand
{
#region Fields
readonly Action<T> _execute = null;
readonly Predicate<T> _canExecute = null;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
/// </summary>
/// <param name="execute">Delegate to execute when Execute is called on the command. This can be null to just hook up a CanExecute delegate.</param>
/// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
public RelayCommand(Action<T> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
///<summary>
///Defines the method that determines whether the command can execute in its current state.
///</summary>
///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
///<returns>
///true if this command can be executed; otherwise, false.
///</returns>
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute((T)parameter);
}
///<summary>
///Occurs when changes occur that affect whether or not the command should execute.
///</summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
///<summary>
///Defines the method to be called when the command is invoked.
///</summary>
///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
public void Execute(object parameter)
{
_execute((T)parameter);
}
#endregion
}
<Window x:Class="AdminTool.SetColdBalance"
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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:AdminTool"
mc:Ignorable="d"
Title="Задать баланс"
Height="150"
Width="250"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"">
<Window.DataContext>
<local:ColdWalletViewModel/>
</Window.DataContext>
<Grid>
<Button Grid.Row="2" Width="100" Height="30" Content="Save" Command="{Binding SaveColdWallets}"/>
</Grid>
</Window>
public class ColdWalletViewModel : BindableBase
{
ICommand _saveColdWallet;
public ICommand SaveColdWallets
{
get
{
return _saveColdWallet ?? (_saveColdWallet = new RelayCommand<object[]>((obj) =>
{
///Тут пишешь что должна выполнять твоя кнопка
}), /*Тут можно написать условие при котором можно будет выполнить данную команду*/);
}
}
}
/// <summary>
/// Implementation of <see cref="INotifyPropertyChanged" /> to simplify models.
/// </summary>
public abstract class BindableBase : INotifyPropertyChanged
{
/// <summary>
/// Multicast event for property change notifications.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Checks if a property already matches a desired value. Sets the property and
/// notifies listeners only when necessary.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="storage">Reference to a property with both getter and setter.</param>
/// <param name="value">Desired value for the property.</param>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers that
/// support CallerMemberName.
/// </param>
/// <returns>
/// True if the value was changed, false if the existing value matched the
/// desired value.
/// </returns>
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
/// <summary>
/// Notifies listeners that a property value has changed.
/// </summary>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers
/// that support <see cref="CallerMemberNameAttribute" />.
/// </param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Create an Animations.cs class
Write these methods there
public void OpenOptions(...) //передаем все необходимые параметры
{ ... }
private void OpenOptions(object sender, RoutedEventArgs e)
{
Animations.OpenOptions(...,...,...);
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question