Резюме для программиста
Вот так приходится делать:
На что люди время своё тратить готовы, лишь бы нормальными языками и фреймворками не пользоваться, где всё это отродясь из коробки есть. ))
Навеяло комментом из соседней темы
дисциплина. организоваать работу так, чтобы прерываться на бумаги, окно, просто откинуться на спинку стула, закрыть глаза и подумать над тем, чем занят. от пяленья в монитор гениальные решения редким идиотам приходят (их гениальность соответствует). настоящие приходят часто просто ночью, во сне. за питьем кофе, беседой с коллегами, ...
На дверях комнаты было написано что-то не совсем понятное: "Однодневная творческая путевка.
"Полнообъемные творческие отпуска от двух недель (рассказ-новелла) до одного года (роман, трилогия). Ялта, Суук-Су, Боровое, Цихидзири, Махинджаури, Ленинград (Зимний дворец)".
А ведь после творчества нужно ещё и отдохнуть! На это обычный отпуск должен выделяться. Ну а потом - снова за работу - в Ялту, к пальмам, к "мулаткам"! И всё это перемежая порционными судачками а натюрель, стерлядью кусками, переложенной раковыми шейками и свежей икрой, яйцами кокотт с шампиньоновым пюре в чашечках, филейчиками из дроздов с трюфелями, перепелами по-генуэзски и тарелочкой супа прентаньер. На веранде, в тени вьющегося винограда, под звуки джаза и с вежливой услугой. А как же иначе? По-другому вдохновение не приходит! Вобщем, работаем не покладая рук.
Полнообъемные творческие отпуска... до одного года.
отпуска...
до одного года...
(тянется за ружьём...)
Не помню, кто-то тут пытался до меня перейти на Blazor, но тему не найду. Хочу задать пару вопросов. Кто-нибудь отзовётся?
Думал, это только у МС беготня по фреймворкам и парад трупов. А нет - Гугл тоже не отстаёт. Выпустили в 2011, последний релиз в 2015. Всё, уже deprecated.
Вообще, этот WebAssembly какая-то хрень. Все с ней носятся уже несколько лет как с серебрянной пулей, но ни одного зрелого и надёжного фреймворка нет. В вебе продолжается разброд и шатание всяких технологий и фреймворков, и год от года только множится каша и пополняется кладбище разных "прорывных" проектов. Начнёшь проект на одном фреймворке, а через пару лет, как заканчивать будешь, он уже deprecated и ФААНГи орут о новом супер-пупер фреймворке.
А нет - Гугл тоже не отстаёт. Выпустили в 2011, последний релиз в 2015. Всё, уже deprecate
У них вроде запускается WebAssembly.
Кто-нибудь на WPF с такой байдой встречался?
В полях для ввода вводишь числа, и если валидация стоит на число с плавающей запятой и на изменение свойства (т.е. считай на ввод каждого символа), то эту самую запятую ввести и нельзя простым способом:
mvvm - WPF: Textbox and Binding to Double not able to type . on it - Stack Overflow
Это в новых версиях фреймворка после 4.0, а в старых - можно. Потому что МС захотела поменять это свойство.
Вот здесь описание проблемы Numeric text box data binding – www.mobilemotion.eu
Пипец, блин. Теперь любое старое приложение не работает нормально при обновлении версии. И хрен ты найдёшь ошибку. А клиенты со всех сторон наседуют - чё за фигня, не могу числа вводить?! И ты такой ищешь, ищешь, в чём же проблема - вроде, все валидации нормально работают, модели нормально написаны. А оно не даёт ввести точку или запятую с клавиатуры! И теперь КАЖДОЕ приложение должно быть написано с такой строкой как можно раньше при старте приложения (т.е. в классе App)
System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty =
false
;
Либо нужно прикручивать костыли (как в ответах на Stackoverflow) там, где раньше всё работало из коробки.
Просто попробуйте как в этой статье создать новый WPF проект и добавить текст бокс с привязкой к модели по свойству с плавающей запятой. Там главное - поставить обновление источника в байндинге не дефолтное, а по изменению свойства. С дефолтным баг не воспроизводится
<TextBox Text="{Binding Path=MyDouble, UpdateSourceTrigger=PropertyChanged}" />
Класс главного окна - тут просто контекст данных устанавливаем
public MainWindow() { InitializeComponent(); DataContext = new ViewModel(); }
Вот разметка окна - просто текст бокс кидаем и ставим байндинг
<Window x:Class="WpfApp1.MainWindow" 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:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800" d:DataContext="{d:DesignInstance Type=local:ViewModel}"> <Grid> <TextBox Text="{Binding Path=MyDouble, UpdateSourceTrigger=PropertyChanged}" /> </Grid> </Window>
Ну и вью модель простая для привязки
public class ViewModel : INotifyPropertyChanged { #region INotifyPropertyChanged Members [field: NonSerialized] public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion INotifyPropertyChanged Members double _myDouble; public double MyDouble { get => _myDouble; set { _myDouble = value; OnPropertyChanged(); } } }
В версиях 4.0 и младше баг не воспроизводится. В старших - воспроизводится. Причём что в 4.х, что в 5.0.
Нафига МС это сделала - непонятно. Может, там какие-то свои баги исправили. Но об этом никому не сообщили, и теперь куча народа с этой хернёй мается и должна откуда-то узнать, что теперь надо постоянно этот костыль вставлять куда-нибудь поближе к старту приложения (это свойство нельзя поменять потом).
Плавающая запятая вставляется из буфера обмена, но с клавы ввести нельзя. Никакую - ни точку, ни запятую (в зависимости от выбранной локали). В статье описывается, почему.
Ещё заметил такую штуку - можно ввести плавающую запятую первым символом, а потом цифры. Т.е. ввести дробное значение меньше 1. Но если вводить после любых цифт - т.е. дробное значение больше 1 - то не вводится.
Лечится либо добавлением этой строки как можно раньше при старте приложения
System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty =
false
;
либо костылями: задержками привязок, добавлением своих конвертеров во все байндинги даже там, где раньше всё работало без конвертеров по дефолту, ну и прочими штуками, как на Stackoverflow насоветовали.
Я такую штуку вписываю
// The inability to enter sometimes the floating point in text boxes comes from the Microsoft's changes in.NET Framework after version 4.0. // The solution is to change the KeepTextBoxDisplaySynchronizedWithTextProperty property to false as early as possible in the application - better in App class constructor. // https://www.mobilemotion.eu/?p=1855 // https://docs.microsoft.com/en-us/dotnet/api/system.windows.frameworkcompatibilitypreferences.keeptextbox //displaysynchronizedwithtextproperty?redirectedfrom=MSDN&view=windowsdesktop-6.0&viewFallbackFrom=net-5.0#remarks System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
В нормальных проектах всегда пользовали Devexpress или Telerik
<TextBox Text="{Binding DoubleValue,StringFormat=N2}" PreviewTextInput="NumberValidator" />
Это вы уже свою логику, форматирование и валидаторов добавили. Я же не говорил, что это нерешаемая проблема. Можно обойти как угодно - кастомным конвертером, например. Проблема в том, что раньше работало по-умолчанию, а теперь без обмазки дополнительным кодом или разметкой вдруг перестало работать. И все старые проекты, написанные на 4.0- версиях фреймворка и где нет всяких обмазок, вдруг стали багованные.
Вот обошли заданием форматирования как у вас https://stackoverflow.com/a/31131932/5015385.
Можно своим конвертером.
Там по ссылке ещё монстрячат всякие простыни кода.
Но всё это надо на каждую проперть с плавающей точкой и привязкой к текстбоксу применять.
А можно одно свойство глобально заменить, как я показал.
Если вы с самого начала использования WPF всегда обмазывались тоннами кастомным фреймворков, своих собственных валидаторов, форматтеров и конвертеров, никогда не используя "чистые" вещи, то у вас это могло ни разу и не всплыть.
Я, например, этот ваш код с сеттером, в котором вызывается метод установки свойств, не понимаю. Я когда-то похожее самописное делал, а потом понял, что если долго это не видеть, а потом вернуться, то непонятно, что происходит - приходится снова лезть в вызовы, где там на самом деле происходит присвоение и когда проходит оповещение об изменении свойства. А чел, который после обычной статьи по MVVM придёт, вообще эту кашу не поймёт. У вас обычный сеттер превратился в кучу вызовов из намонстряченных сверху обёрток и "улучшателей". А если я хочу добавить ещё логики в сеттер, мне куда её поместить? До вызова вашего метода, после, или прямо в него?
В некоторых фирмах заставляют проекты на каких-то технологиях начинать всегда с неких корпоративных шаблонов, а не с нуля. Типа, того же WPF - есть шаблон, где уже настроен главный класс приложения (App), присоединены нужные библиотеки и корпоративные фреймворки, настроены нужные инжекторы, проинжектированы нужные сервисы, логгеры, настроены стили, пофикшены всякие баги установками нужных свойств (типа как выше описано), добавлены переменные с нужными путями для проекта (типа логов ошибок, файлов сохранений, настроек и т.п.), чтобы чел не занимался самодеятельностью, куда чего писать, и прочее. Т.е. ты каждый раз не с нуля проект начинаешь, а уже с шаблона, накачанного кодом по самое небалуйся. Главный альфа-кодер на фирме создал. ))
Можно обойти как угодно
А никто и не собирался ничего обходить просто сделал так как посчитал более удобным. Да и так тоже работает, хотя никогда бы и в голову не пришло пользовать
<TextBox Text="{Binding DoubleValue}" Width="150" HorizontalAlignment="Left" Margin="5"></TextBox>
никогда не используя "чистые" вещи
Всё нужно пользовать "правильно".
метод установки свойств, не понимаю
Ну так это уже ваши проблемы
Гораздо удобнее чем везде писать If
А если я хочу добавить ещё логики в сеттер
вообще то сеттер не предназначен для добавления логики. Но если очень хочется, то SetProperty возвращает bool
Начинать всегда с неких корпоративных шаблонов, а не с нуля.
А в чём проблема то? Если там всё по уму сделано.
А если нет так нужно просто указать на недостатки и методы их исправления. Или хотя бы поинтересоваться, а почему именно так сделано?
А никто и не собирался ничего обходить просто сделал так как посчитал более удобным. Да и так тоже работает, хотя никогда бы и в голову не пришло пользовать
Как не пришло, когда дефолтный триггер на обновление свойства для тектовых полей - потеря фокуса? А чтобы сделать валидацию на каждый введённый символ (частая задача - проверка правильности ввода "на лету"), нужно явно указать UpdateSourceTrigger. Вот после этого баг и возникает. Я проверял на версиях 3.5, 4.0, 4.1, 4.5, 5.0. На 6.0 не знаю.
Там вся соль именно в установке UpdateSourceTrigger на изменение свойства - т.е. ввод любого символа. Если оставить на потерю фокуса, как по дефолту, то вводить можно что угодно - триггер не срабатывает, и через привязку ничего не уходит. А именно из-за этого срабатывания удаляется первый введённый символ плавающей запятой. При этом можно ввести уже готовое число с плавающей запятой из буфера обмена. Я статью приводил - там это описано.
Ну так это уже ваши проблемы
Гораздо удобнее чем везде писать If
Какой if, вы о чём? Если о проверке, равно ли новое значение старому, то я в этом смысла не вижу. В большинстве случаев на это всё равно, и просто присваиваешь новое старому, даже если они равны. Если где-то логика приложения к этому критична, и надо случай одинаковых старого и нового значения отдельно обработать - просто делаешь отдельно для этого места проверку. В остальных случаях это лишние движения.
Я потому и отказался от универсальных сеттеров, потому что в разных местах надо логику немного поменять. Поэтому от универсальности сеттера не остаётся следа. Вы же эту свою строку SetProperty(value...) чего-то там пихаете в каждый сеттер копипастом? А в чём смысл? Просто меньше копипастить, чем раньше с if'ами? Если так лень копипастить и писать одинаковый код, то можно эту строку с SetProperty или блок с if'ом в сниппет запихать.
вообще то сеттер не предназначен для добавления логики
А то что?
Местный альфакодер запретил?