TargetType и создание наследника класса — самый простой и удобный способ. Если у вас несколько вариантов стилей одной и той же кнопки — сделайте базовый стиль и базовую кнопку, а вариации стилей через свойства задайте. Тогда и не нужно будет создавать несколько классов одной и той же кнопки. Дополнительные классы нужны для использования дополнительных свойств только. И это нормально, когда у вас есть какие-то компоненты с базовыми свойствами и несколько их наследников с дополнительными. Можно, конечно, в рантайме в коде вертеть как угодно стилями, но в WPF традиционен подход в виде шаблона MVVP и вот так в коде всем вертеть будет не очень удобно. Такой подход используется в случаях сложных или нестандартных контролов.IconButton и TabButton как расширение стандартного класса Button. Так же у них определены свои собственные одноимённые стили. И далее в коде используются обе эти кнопки, при этом у них есть как общий базовый стиль, так и добавленные свойства типа иконки или заголовка вкладки, которые и используются в XAML разметке. При этом, т.к. они имеют общего предка, можно легко добавить стиль для класса Button и поменять базовый стиль сразу для всех наследников, не затрагивая дополнительные стили самих наследников.Grid (очень, очень рекомендую для замены DataGrid, т.к. там очень плохо с адекватным размещением и позиционированием контента); ComboBoxEx — исправление размеров контента в соответствии с самим элементом.System.Text.Json нет такой фичи: https://github.com/dotnet/runtime/issues/38049Newtonsoft и аттрибут OnError: https://www.newtonsoft.com/json/help/html/Serializ...Command="Exitfoo"CommandBinding.Command Property: https://learn.microsoft.com/en-us/dotnet/api/syste...ApplicationCommands Class: https://learn.microsoft.com/en-us/dotnet/api/syste...Ctrl+W для выхода из приложения является контр-интуитивным и использовать такой хоткей для выхода из приложения нельзя, т.к. этот хоткей традиционно используется для закрытия вкладок. Кроме того, винда имеет стандартный хоткей Alt+F4 для закрытия окна или выхода из приложения.Command — т.к. это всё XML, то там строка и из этой строки надо сделать конвертацию в тот тип, который указан в классе CommandBinding для свойства Command, а именно в тип, реализующий интерфейс ICommand.Window через цепочку наследования в предках есть класс UIElement, который и реализует свойство привязки команд через коллекцию:public class System.Windows.UIElement : Visual, IInputElement, IAnimatable
{
public CommandBindingCollection CommandBindings { get; }
}public class System.Windows.Input.CommandBinding
{
public ICommand Command { get; set; }
}ICommand, а именно в класс System.Windows.Input.RoutedUICommand(src). Соответственно список этих команд находится в статическом классе System.Windows.Input.ApplicationCommands, среди которых и происходит поиск нужной команды. Костыльно? Да, костыльно, ну хотя бы работает. if (item != null
&& item.GetType().GetInterfaces().Any(
i => i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
)
{
IEnumerable<object> collection = (IEnumerable<object>)item;
} public class MyForm : Form
{
protected override void WndProc(ref Message m)
{
if(m.Msg == WM_MOUSEWHEEL)
{
// ...
return;
};
base.WndProc(ref m);
}
} Zenject зачем добавлять к SceneLoader наследование от ISceneLoader
чтобы потом указывать ISceneLoader как тип
хотя если указать просто SceneLoader как тип ничего не изменится
public interface IFoo
{
public string Name { get; set; }
}
public class Bar1(string name) : IFoo
{
public string Name { get; set; } = name;
}
public class Bar2(string name) : IFoo
{
public string Name { get; set; } = name;
}List<IFoo> list = [
new Bar1("Bar 1"),
new Bar2("Bar 2")
];
foreach (IFoo foo in list)
{
Console.WriteLine(foo.Name);
}Bar 1
Bar 2public System.Windows.Media.ImageSource Source { get; set; }TestImage2.Source = new BitmapImage(LoadedUri);Uri, а в тип BitmapImage. Ну или просто завести сразу свойство нужного типа.var LoadedUri = (Uri)stringToUriConverter.Convert(a, typeof(BitmapImage), null, CultureInfo.CurrentCulture);Grid с добавленными свойствами шаблонов для заголовков и ячеек, а так же своим движком для рендернинга таблицы (строк, столбцы, заголовки). Main поймать нельзя.Exception и указывая параметры исключений /// <summary>
/// Localized exception
/// </summary>
/// <param name="stringId">i18n string Id</param>
/// <param name="args">String arguments for format</param>
public class I18nException(string stringId, object[] args)
: Exception(
string.Format(
I18n($"{ExceptionId} {stringId}"),
args))
{
public readonly object[] Args = args;
public readonly string StringId = stringId;
private const string ExceptionId = "Exception";
}I18n(string str) - функция для получения локализованной строки для текущего языка приложения. public class ElementNotFoundException(Type type, string name)
: I18nException(
"Element not found",
[type.FullName, name]
)
{
public readonly string ElementName = name;
public readonly Type ElementType = type;
}(тыц). перевод игры лежит в отдельном файле(например json и хранит в себе каждую строчку текста, которая применяется в игре), и потом в коде запрашивать нужную строку из файла и брать от туда значение текста для последующего применения на сцене
или есть способы попроще