Заморочка интересная с WPF binding
знаю, что всего там еще не перевидал, но все же достаточно много.
наверное, неправильный выбрал дезигн, но лучше расскажу по порядку.
делаю UserControl, в котором, кроме прочего есть несколько клавиш, которые нужно периодически конфигурировать. т.е. делать их видимыми/активными...
для этого решил добавить к контролу DependencyProperty типа некого объекта. в окне, в которое вставлен контрол, этому проперти присвоено значение Binding, объект, который лежит в DataContext, имеет соответствующий проперти и говорит периодически OnPropertyChanged ("blablabla");
наблюдаю картину, которую не ожидал увидеть, и не сразу понял, в чем дело.
в этом же контроле имеются и другие DependencyProperties, которые типа примитивов: строки, целые ... некоторые я использую просто чтобы "передать сообщение" контролу. само проперти у объекта DataContext просто всегда возвращает одно и то же значение, просто пишу OnPropertyChanged ("blablabla");, и в PropertyChangedCallback юзэрконтрола делаю что надо по этому событию.
но те, где проперти типа объект, ведут себя не как ожидал. их нужно действительно поменять, причем не что-то там у них внутри, а другой объект прислать, иначе по OnPropertyChanged ("blablabla") происходит считывание объекта из DataContext, но PropertyChangedCallback не вызывается! т.е., например, если ваш объект - это, например, List(string), вы его создали и OnPropertyChanged ("blablabla"), PropertyChangedCallback вызовется. затем допишете к этому списку еще строчечку и снова вызовете OnPropertyChanged ("blablabla") - уйдет как в болото, и даже круги не пойдут. "оно" уже имеет тот же самый объект, и делать ничего не хочет. т.е. вы должны слать новый объеат. например, брать ваш список и делать public List(string) superlist { get { return _superlist.ToList(); }}, и тогда оно сработает.
допускаю, что это только для меня оказалось новостью, а для остальных - "и дураку понятно", но я пару часов протупил, решил исповедоваться : (
Сорри, что написано вроде как понятно, но в чем проблема так и не понял. Какое нибудь приложение есть, что неправильно работает?
Ну и у меня OnPropertyChanged () или со старыми версиями OnPropertyChanged (nameof(PropertyName));
Snoop пользовали?
Да, и для UI исрользую ObservableCollection<T>, а не List
у меня не лист, а "свой объект". я список просто взял для примера. мог взять все что угодно кроме примитива.
проблема в том, что я не нашел лучшего дезигнерского решения что-нибудь перенастроить в контроле, кроме как вделать ему дэпэндэнси пропэрти и через типа обновление оного заставить контрол реагировать на событие. и оно срабатывает, если каждый раз передавать новую копию, а не тот же измененный объеат. хэндл должен быть не тот же, что при последнем обновлении.
все вроде теперь заработало, но нужно поковырять другие возможные варианты.
чтобы вас не отвлекать на List, ObservableCollection и прочую муть, возьмем класс
public class Person { public string Name { get; set; } public int Age { get; set; } public Person (string n, int a){ Name = n; Age = a; } }
так вот если вы сделаете так:
private Person _person = new Person ("Name0", 10); public Person person { get { return _person; }} ... _person.Age++; OnPropertyChanged ("person"); ...
, то тичего не произойдет.
а так - другое дело
_person = new Person (_person.Name, _person.Age+1); OnPropertyChanged ("person");
и оно срабатывает, если каждый раз передавать новую копию, а не тот же измененный объект
Ну так абсолютно правильно срабатывает. Проперти то на объект, а не на его содержимое.
Если нужно отслеживать изменения в объекте, то объект нужно наследовать от INotifyPropertyChanged хотя бы.
Именно по этой причины для меняющегося списка вместо List используется ObservableCollection.
Ну давайте так.
- Что может определить обычная проперть? Только то что ее значение изменилось. Что там происходит с объектом она просто так узнать не может.
Что бы определять изменение объекта нужно еще иметь какую то договоренность. Одна из них INotifyPropertyChanged интерфейс.
Так что изменение объекта нужно отслеживать самостоятельно, если его поля не используются напрямую в юсер контроле.
Счас еще гляну, что там Маркс с Энгельсом написали по этому поводу. Поумнее тогда ответ будет.
https://docs.microsoft.com/en-us/dotnet/api/system.windows...
To detect source changes in one-way or two-way bindings, the source must
implement a suitable property change notification mechanism such as INotifyPropertyChanged.
хтмл5 еще выбесительнее. думаю, GUI еще ожидает возрождение в каком-нибудь гениальном языке его описания.
на сегодня хамл - наиболее удачное из всего что есть. ваши девки-монстры ужасны что в хтмл5, что в хамл.
не нравится хамл - учитесь говорить на opengl
это уже - из области философии
Никак нет - чистое программирование
Если я хочу узнать изменилось ли что внутри объекта мне нужен канал обратной связи от объекта. В котором объект мне скажет, что его состояние изменилось.
Можно конечно еще поизвращаться на предмет сравнения сериализованной копии объекта или еще как. Но нам то извращения не нужны.
Или есть еще другая точка зрения?
хтмл5 еще выбесительнее. думаю,
А ничего что большие компании перешли на десктопные веб App? https://ru.wikipedia.org/wiki/Electron С ElectronJS начал программировать несколько месяцев назад.
Допустим Visual Studio Code полностью написана на HTML5 и JavaScript - https://www.electronjs.org/apps/visual-studio-code
Тоже самое с Twitch - https://www.electronjs.org/apps/twitch
И скайп - https://www.electronjs.org/apps/skype
Моё любимое приложение Pencil которым я уже минимум как год пользуюсь - https://www.electronjs.org/apps/pencil
Единственный минус пока полупрозрачность в Windows 8.x глючит вроде как - https://github.com/arkenthera/electron-vibrancy/blob/maste...
Мне понравилось как получилось вот это десктопной веб App:
P.S. Допустим пишишь на HTML5 и JavaScript, а потом своё веб приложение переносишь в KaiOS https://kaiosinfo.ru/programmirovanie или вообще в Ionic - https://ionicframework.com/docs
- учитесь говорить на opengl
Зачем когда есть ThreeJS для ElectronsJS? https://github.com/jeromeetienne/electron-threejs-example а вместо Ajax net.Request - https://www.electronjs.org/docs/api/client-request
private Person _person = new Person ("Name0", 10); public Person person { get { return _person; }} ... _person.Age++; OnPropertyChanged ("person"); ...
, то тичего не произойдет.
Аболютно верно. Правильное поведение.
а так - другое дело
_person = new Person (_person.Name, _person.Age+1); OnPropertyChanged ("person");
И снова совершенно верно. Правильное поведение. В первом примере значение поля "person" не изменилось, как указывало оно на что-то вроде 0x2376894A, так и продолжило на него указывать.
Во втором случае значение "person" изменилось. Новый объект, новый адрес. Даже на такое среагирует (возраст не меняем):
_person = new Person (_person.Name, _person.Age);
Хотя с точки зрения банальной эрудиции как раз сейчас-то у нас в проперти "person" ничего не изменилось.
Похоже на разницу в == и equals()
ViewModel:
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainViewModel()
{
Foo = new RelayCommand(Do_Foo);
}
private Person _person = new Person("John Smith", 33);
public Person Person
{
get
{
return _person;
}
}
public ICommand Foo { get; private set; }
private void Do_Foo(object obj)
{
_person.Age++;
PropertyChanged(this, new PropertyChangedEventArgs("Person"));
}
}
XAML:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<StackPanel>
<TextBlock>
<Run Text="Person name:" />
<Run Text="{Binding Person.Name, Mode=OneWay}" />
</TextBlock>
<TextBlock>
<Run Text="Person age:" />
<Run Text="{Binding Person.Age, Mode=OneWay}" />
</TextBlock>
<Button Content="Do Foo" Command="{Binding Foo}" />
</StackPanel>
</Window>
Работает.
Или есть еще другая точка зрения?
есть точка зрения, что мы пытаемся решать наши задачи, используя имеющиеся методы и парадигмы. для этого полезно знать, как они работают. один из аспектов я попытался изложить в первом посте.
вы тут же вспомнили почему-то INotifyPropertyChanged и ObservableCollection. с моей точки зрения, извините - некстати, спросил при чем тут это, вы так и не пояснили.
давайте будем считать, что проехали?
один из аспектов я попытался изложить в первом посте.
Сорри, тогда я так и не понял что именно вы хотели там пояснить.
Всё что понял - это то dependency property не реагирует на изменение внутреннего состояния объекта. При этом правильно не реагирует.
спросил при чем тут это, вы так и не пояснили
Ну так уже который раз пытаюсь это сделать но Вы совершенно не хотите в этом процессе участвовать.
с моей точки зрения, извините - некстати
ну с моей точки зрения, именно в этом проблема и заключается. Но если вы считаете это тупиком и не желаете даже смотреть в эту сторону, то я никак не смогу это изменить.
Пытался уже заходить с совершенно разных сторон, но вы никак не хотите обсуждать и эти аспекты.
давайте будем считать, что проехали?
Ну если вы изложите точно что вам требуется, я еще могу попробовать сделать пример.
Хотите контрол с двумя кнопочками, управляемый внешним объектом?
Сорри, тогда я так и не понял что именно вы хотели там пояснить.
как вы тогде вообще что-то начали высказывать? логичным было бы начать с того, что не понял. я вот вас не понял - спрашиваю, а не утверждаю (пока), что это - бред. а у вас уже без понимания решение лежит.
Ну если вы изложите точно что вам требуется, я еще могу попробовать сделать пример.
зачем? вы ведь уже поняли?
Хотите контрол с двумя кнопочками, управляемый внешним объектом?
не знаю, что это такое, но очень хочу : )
логичным было бы начать с того, что не понял
сразу первый пост
Сорри, что написано вроде как понятно, но в чем проблема так и не понял.
не знаю, что это такое, но очень хочу
Да не за что. Я только до сих и не знаю правильно Вас понял или нет. С одной стороны вроде бы да, а судя по реакции нет.
Специально сделал DepencyProperty принимающий объект, который присваивается только раз, но вот менять состояние этого объекта можно сколько угодно. По крайней мере, именно так я понял Вашу проблему.
Если что не так, меняйте как требуется, бум разбираться дальше.
посмотрел. не заработало, пока не добавил в хамле основного окна DataContext ("нормальный", не DesignInstance).
после этого заработало. клацаешь на чекбоксы, клавиши появляются/исчезают.
но мне кажется, было бы проще и понятней вместо создания DependencyProperty в SampleUserControl.cs (лишнего, мне кажется), просто описать в MainWindow.xaml этот контрол вот так
<Views:SampleUserControl DataContext="{Binding StateContainerMain}" />
и будет достигнута та же цель: присвоение контролу DataContext.
кроме того, я начинал всю эту ветку о том, как срабатывает изменение OnPropertyChanged, где property - DependencyProperty типа object. мне кажется, Visibility - это enum, и срабатывает все как и в случае примитива.
т.е. я не понял, что этот пример мне хотел продемонстрировать/предложить.
но посмотреть было интересно. еще раз спасибо : )
посмотрел. не заработало, пока не добавил в хамле основного окна DataContext ("нормальный", не DesignInstance).
Странно и ехе не заработало? DesignInstance я для решарпера делаю. Код и ехе от одного бильда.
но мне кажется, было бы проще и понятней вместо создания DependencyProperty
Ну так специально ради использования DependencyProperty и сделал и специально указал, что пример. Я так никогда и не делаю
как срабатывает изменение OnPropertyChanged, где property - DependencyProperty типа object
Смысл остается тем же, нужно еще что то, что говорит об изменении самого объекта.
Сделаем и с объектом... тоже есть варианты, возьмем, как говорите, самый дебильный
еще одна заморочка. пишем
EventManager.RegisterClassHandler(typeof(Window), System.Windows.Controls.Control.KeyDownEvent, new KeyEventHandler(keyDown), true);
keyDown выглядит так:
void keyDown(object sender, KeyEventArgs e) {
как узнать, который из альтов был нажат, левый или правый? в e.KeyboardDevice.Modifiers в обоих случаях стоит просто Alt. ясно, можно опросить все клавиши на предмет нажата или нет, но это неудобно, хотелось бы попроще. может, в этом "е" вся инфа уже имеется, я ее просто не вижу?
я не призываю вас делать "дебильные вещи". и вообще никаких вопросов в моем первом посту не содержится. я просто опыт свой печальный описал. вижу, для вас то, что мне было неизвестно, просто очевидно. молодец! вайтер зо! : )
это то, что видно при нажатии алта. без проблем, но это мне известно и не нужно. вы скажите, как при нажатии, скажем, клавиши 'A' определить, нажат ли при этом ПРАВЫЙ алт? я не хочу запоминать его состояние когда его опускают-поднимают.
но мне уже это просто интересно, но не необходимо, я совсем другое решение придумал.
в e.KeyboardDevice.Modifiers в обоих случаях стоит просто Alt
А у меня нет
Левый alt = Alt Правый alt = ALT, Control
Можно еще и так проверить, но надежного способа пока не нашел. Чтобы работал при любой последовательности нажатий.
KeyStates keyState1 = e.KeyboardDevice.GetKeyStates(Key.LeftAlt);
KeyStates keyState2 = e.KeyboardDevice.GetKeyStates(Key.RightAlt);
не а. Винда английская, а раскладка была русской, да и не зависит от раскладки. Только что попереключал.
Значит не от раскладки, давно я не брал в руки шашек. Но Alt+Ctrl вместо правого альта посылают "немецкие" клавиатуры у которых Alt Gr вместо правого Alt.
делает что-то другое?
Ну оно же должно само ещё и внутри person-а за всеми полями следить!
В этом же расстройство было. Вешаем OnChange на проперть person и возмущаемся а почему оно само не следит что у объекта, на который указывает person, пропертя меняются.
А ты предлагаешь самому, ручками за person.age следить. Ни стыда ни совести! :)
А ты предлагаешь самому, ручками за person.age следить. Ни стыда ни совести! :)
Не предлагаю :) Код 1 в 1 как у moose:
_person.Age++; OnPropertyChanged ("person");
и мой:
_person.Age++; PropertyChanged(this, new PropertyChangedEventArgs("Person"));
В чем тут разница? :)
PS: Person в моем примере не унаследована от INotifyPropertyChanged (если ты об этом)
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string n, int a)
{
Name = n;
Age = a;
}
}
PropertyChanged(this, new PropertyChangedEventArgs("Person"));
Для демки, конечно никакой разницы. Но иметь такое в нормальной проге
Обычно так
PropertyChanged();
Раньше было так
PropertyChanged(nameof(Person));
В разных расширениях может быть еще встроенная проверка на ==, соответсвенно количество аргументов чуть больше
Для демки, конечно никакой разницы.
Ну так об этом и речь.
Обычно такPropertyChanged();
Раньше было такPropertyChanged(nameof(Person));
В разных расширениях может быть еще встроенная проверка на ==, соответсвенно количество аргументов чуть больше
Это все мило, но не имеет никакого отношения к заданному вопросу.
UI обновляется проверти после вызова эвента PropertyChanged. Обновилось там значение или нет - не важно, геттер будет вызван.
Код OnPropertyChanged moose не привел. Что он там делает и как проверяет - остается за кадром. Если он проверяет объект на == , то это уже его тараканы. Могбы тогда проверить на null и дергать PropertyChanged только если предыдущее значение было null, а потом удивляться, почему оно так работает
Левый alt = Alt Правый alt = ALT
-----
Ты не совсем прав.
Скан-код будет один и тот же, но префикс будет другим.
https://docs.microsoft.com/en-us/windows/win32/api/winuser...
Чтобы работал при любой последовательности нажатий.
-----
Там нет последовательности.
Там есть информация об состоянии служебных (шифт, альт, контрол) клавиш на момент нажатия альфа-цифрo-буквы.
Это все мило, но не имеет никакого отношения к заданному вопросу.UI обновляется проверти после вызова эвента PropertyChanged. Обновилось там значение или нет - не важно, геттер будет вызван.Код OnPropertyChangedmoose не привел. Что он там делает и как проверяет - остается за кадром. Если он проверяет объект на == , то это уже его тараканы. Могбы тогда проверить на null и дергать PropertyChanged только если предыдущее значение было null, а потом удивляться, почему оно так работает
Уже давно надо было перейти с WPF на HTML... а не париться с десктопным приложением. Когда я в колледже учился, нам вбивали в голову про кроссплатформенность, WPF не является такой, например они сами от Silverlight отказались https://ru.wikipedia.org/wiki/Microsoft_Silverlight.
В 2012 году Microsoft назначила конец жизненного цикла Silverlight 5 на 10 декабря 2021 года. В 2013 году Microsoft объявила, что они прекратили развитие Silverlight, за исключением выпуска исправлений ошибок. Silverlight более не поддерживается в браузерах Opera, Mozilla Firefox, Google Chrome, так как в 2015 году в этих браузерах была отключена по умолчанию или полностью прекращена поддержка плагинов формата NPAPI.
P.S.:У WPF её нисша это визуализация данных, а не работа с формами, и больше подходит для HMI/SCADA, а не как типичное десктопное приложение. Мне один умный дотнетчик сказал, чтобы я на HTML5 переходил, хотя он большой фанат C#/.NET.
Скан-код будет один и тот же, но префикс будет другим.
Это если в консоли постоянно опрашивать всё.
Здесь же речь идет конкретно об этом:
EventManager.RegisterClassHandler(typeof(Window), System.Windows.Controls.Control.KeyDownEvent, new KeyEventHandler(OnKeyDown), true) private void OnKeyDown(object sender, KeyEventArgs e) { ... }
То бишь мы получаем исключительно KeyDown события и не хотим сканировать KeyStates ,а хотим пользовать e.Key с каким то флагом
Можешь с ехе поиграться. Там в первой строке e.Key, а затем коды нажатых клавиш из отсканированных KeyStates
Код OnPropertyChangedmoose не привел. Что он там делает и как проверяет - остается за кадром. Если он проверяет объект на == , то это уже его тараканы. Могбы тогда проверить на null и дергать PropertyChanged только если предыдущее значение было null, а потом удивляться, почему оно так работает
мы еще не видали, но осуждаем : )
... не обижался? который из них?
Тут написано https://ru.wikipedia.org/wiki/Windows_Presentation_Foundat...:
Windows Presentation Foundation (WPF) — аналог WinForms, система для построения клиентских приложений Windows с визуально привлекательными возможностями взаимодействия с пользователем, графическая (презентационная) подсистема в составе .NET Framework (начиная с версии 3.0), использующая язык XAML.
Допустим захотят отказаться от WPF или от NET, эти знания уже будут бесполезными, и всё прийдётся переучивать с нуля.
Уже давно надо было перейти с WPF на HTML... а не париться с десктопным приложением.
Почему? Ведь если ты делаешь десктопное приложение, то WPF как раз то, что доктор прописал :)
Когда я в колледже учился, нам вбивали в голову про кроссплатформенность
Кроссплатформенность нужно далеко не всем. Более того, в большинстве случаев она не нужна.
например они сами от Silverlight отказались
Технология не выдержала конкуренции и умерла. Ничего необычного в этом нет.
Мне один умный дотнетчик сказал, чтобы я на HTML5 переходил, хотя он большой фанат C#/.NET.Мне кажется, что у каждой технологии есть свое преминение. Я не вижу смысла переходить на HTML в десктопном прилежении.
в этом же контроле имеются и другие DependencyProperties, которые типа примитивов: строки, целые ... некоторые я использую просто чтобы "передать сообщение" контролу. само проперти у объекта DataContext просто всегда возвращает одно и то же значение, просто пишу OnPropertyChanged ("blablabla");, и в PropertyChangedCallback юзэрконтрола делаю что надо по этому событию.
это я написал? это - брэхня! странно, что уважаемое комъюнити не возразило. я уже не могу знать, почему я так решил, видимо, на тот момент было что-то, что такое впечатление создало. это - тоже не работает, как я ожидал.
видимо, где-то "в междуящичном пространстве" происходит какая-то оптимизация, и если гэттэр возвращает то же значение, что уже стоит в контроле, его PropertyChangedCallback не вызывается. единственный выход - передавать каждый раз значение отличное от предыдущего.
вообще, повторю, мне не нравится как я сделал дезигн. мне нужно, чтобы контрол реагировал на события, при этом выполнял некоторые действия, связанные с новым значением (свойствами) некого объекта. ДАЖЕ ЕСЛИ ОБЪЕКТ НЕ ИЗВЕНИЛСЯ! решил воспользоваться байндингом, дабы не нарушать святых принципов mvvm/ но вот получается такая штука как описываю. можно, конечно, чтобы адаптер бросал событие, на которое контрол бы подписался, но это некошер. как еще юзырь-контрол завтавить на что-то отреагировать, используя какие-то данные?
пока оставляю все как есть. естественно, каждый раз беспокоясь о том, чтобы был новый объект.
Это если в консоли постоянно опрашивать всё.
-----
Это при каждом нажатии.
Опрашивать - можно, но не нужно - все и так будет.
Если мало того что идет в данных евента - можно взять что-то что мелкомягкие делали для игрушек - там точно отслеживаются все изменения состояния клавиатуры.
хотим пользовать e.Key с
-----
Не помню что есть в этих эвентах - давно не работал с клавой на этом уровне.
Возможно, что что-то обрезали, но скорее всего где-то что-то оставили... возможно - неявное, недокументированноe...
но скорее всего где-то что-то оставили... возможно - неявное, недокументированноe...
Тебе дать простейшие исходники поиграться?
Нормальные данные нашел только в "массиве состояния" клавиш.
Что то типа "буква"+состояние дополнительных клавиш, не нашел. Да и не должно вроде быть, а то что делать с контрол/стрелка, алт/капс лоск и т.п.
связанные с новым значением (свойствами) некого объекта. ДАЖЕ ЕСЛИ ОБЪЕКТ НЕ ИЗМЕНИЛСЯ!
если у объекта имеется новое значение, то объект вообще то изменился.
Можно ли нормальное описание задачи написать? Наверняка народ чего-то придумает.
мне нужно, чтобы контрол реагировал на события
Зависит еще и от того как будет использоваться контрол, в простейшем случае можно сделать всё через его ViewModel.
Можно еще сделать дополнительный объект "События" и через него всё передавать.
Зависит еще и от того как будет использоваться контрол, в простейшем случае можно сделать всё через его ViewModel.
наверное, это если не оптимальное решение, то очень к нему близко. попробую перелопатить завтра. возможно, кое-какие побочные ляпы исчезнут.
Можно еще сделать дополнительный объект "События" и через него всё передавать.
можно, но для этого контрол должен знать о том классе, который является паблишером, чтобы иметь возможность подписаться. а это - полный некошер.
Почему? Ведь если ты делаешь десктопное приложение, то WPF как раз то, что доктор прописал :)
По многим причинам, по моему мнению WPF медленнее работает, чем допустим WinForms, т.к. в WPF используется DirectX и GDI+, не зря ведь Murr выберает хороший себе компьютер. Я думаю задачу ТС на WinForms можно было сделать в два счёта.
Кроссплатформенность нужно далеко не всем. Более того, в большинстве случаев она не нужна.
С вами не согласен, это вообще-то то, что мы в самом начале учебного года учили, когда я поступил только в колледж, про кроссплатформенность наверное нам семестр рассказывали, если сюда гляните https://sourceforge.net/directory/os:windows/ там слева сверху где OS, там первые три чек-бокса это Windows, Linux, MacOS. А в этой статистики https://gs.statcounter.com/os-market-share Android стоит впереди, за ним Windows и iOS.
Технология не выдержала конкуренции и умерла. Ничего необычного в этом нет.
А кто конкурент? Они просто не смогли портировать на все устройства, а на смартфоне Silverlight хорошо кушает аккумулятор.
Я не вижу смысла переходить на HTML в десктопном прилежении.
Ну меньше возьни, а UI более привлектелен чем у WPF.
Я не вижу смысла переходить на HTML в десктопном прилежении.
Вот одно из моих приложение, простой калькулятор на Electron, фон полупрозачный с blur эффектом, ночью тёмная тема, днём светлая тема. Я ещё для понтов поставил эту CSS библиотеку - https://animate.style/
По многим причинам, по моему мнению WPF медленнее работает, чем допустим WinForms
Мнение интересное, но не вижу бенчмарков :)
не зря ведь Murr выберает хороший себе компьютер.
Ага, исключительно из-за WPF :D
Я думаю задачу ТС на WinForms можно было сделать в два счёта.
На WinForms задолбаешься делать сложные контролы.
С вами не согласен, это вообще-то то, что мы в самом начале учебного года учили, когда я поступил только в колледж, про кроссплатформенность наверное нам семестр рассказывали
То, что вам семестр рассказывали про кроссплатформенность не означает, что она широко применяется. Нам семеместр рассказывали про Lisp, про Prolog и целых 2 семестра рассказывали теорию графов в курсе под названием "базы данных"
А кто конкурент? Они просто не смогли портировать на все устройства, а на смартфоне Silverlight хорошо кушает аккумулятор.
Конкурент HTML+фремворки. Также как и Flash загнулся.
Вечером может быть покажу. Пока я пытался сделать то что делал ТС только на Javascript в стиле WPF/XAML, этот пример должен работать и в Electron. Пока проблема, я не могу обращаться к данным внутри ShadowRoot. Коменты кривые, я в полусонном состояние кодил.
Я бы сказал, что твой пример не работает:
После чего ни имя ни возраст не поменялись.
Ну и разница в паттернах. WPF - это MVVM - View <---> ViewModel <--> Model,т.е. View ничего не знает о Model, а Model ничего не знает о View.
просто найти что еще нажато без скана массива проблема
-----
Это не проблема получения инфы об состоянии клавы.
Если нужно обработать последовательность каких-то нажатий - сделай очередь и складывай туда нажатия.
В принципе, именно так и сделано в досе/винде, но для обработки нажатия вынимаются из очереди по одномu.
Но вот до этой очереди Я как-то не пробовал добираться - не нужно было.
Я думаю задачу ТС на WinForms можно было сделать в два счёта.
когда-то в начале 90-х мне выпало щясьтье оказаться на заработках "чернорабочим" в одной из европейских стран. и там в куче детских игрушек оказался какой-то детский лапатоп, названия не помню, вроде что-то начиналось с "олимп...", но не уверен. там был только бейсик. и я за пару вечеров слепил то, что сейчас пытаюсь вот уже неделю с использованием современных технологий, ускоряющих и упрощающих процесс разработки : )
конечно, я здесь могу гораздо быстрее и проще накрутить кучу всяких других полезных фич, но они все второстепенны.
в те времена меня волновал ответ на один вопрос: как сделать, чтобы оно правильно работало. а теперь (сам себе удивляюсь. не всегда придерживаюсь, но действует на мозк!) - как это "правильно" сделать, чтобы оно хоть как-то работало. а что такое правильно, придумал какой-то мудак (как его, мввм, звали?). а я, похоже, тоже это слово. но я - не один: весь мир повелся. а вроде неглупые люди.
да, AlexNek, сегодня перелопатил проект, создал для контрола отдельный адаптер (его принято называть вьюмодел), все снова работает как и прежде, просто те же самые части кода переместились с одного места (мне кажется, более подходящего) в другое.
мы постоянно гонимся за "повтороиспользованностью", думая почему-то, что все, что мы ваяем - на века, и мы будем использовать это снова и снова. а такого в реальности - менее 1%, я думаю. посему только если встретились с возможностью использовать что-то свое уже где-то созданное хотя бы
еще один раз, стоит заняться рефакторингом и привести это к удобоваримому виду. а до того - плюнуть и делать все как на один раз, только для сейчас. выпердреж с красивым дезигном - единственно из соображений удобства и минимизации затрат на дальнейшую разработку и сопровождение. нахер из головы "посторноиспользуемость"!
и мы будем использовать это снова и снова. а такого в реальности - менее 1%
У меня все же другое мнение. Грубо говоря - если выбирать между говно-кодом за час и хорошим кодом за день. То я выберу все-же второе. Потому как в общем зачете суммарное время будет меньше.
Вот у меня перед глазами есть конкретные проекты. Один планировался на месяца три для замены старого, в итоге уже год как добавляют новое и новое и до сих пор проект не разваливается. А всё потому, что был и изначально правильно построен и дальнейшее проектирование было таким же. При этом отдельные части можно использовать совсем в других проектах, хотя пока это действительно никому не нужно. Зато если ошибка, знаешь, что она может быть только в "этом месте".
создал для контрола отдельный адаптер
Я просто не делаю по другому, всё идет на автомате. Может тесты и не очень волнуют для данного случая, но нет особых проблем использовать данный "адаптер" для тестирования. А вот с вьювом...
Софт и снаружи и внутри должен выглядеть "красиво".
как его, мввм, звали
Никто никого не заставляет использовать какой либо паттерн, можно и пешком ходить в другой город. Но если удобнее на машине или поезде, то отчего бы и нет?
Вот дерево можно обойти многими способами, на "Визитор" паттерн будет удобнее.
Конечно, не следует впадать и в другую крайность - чуть что сразу какой паттерн использовать, нужен он там в этом виде или нет.
Ну да, я же написал, что код ещё не готов, хотел сделать в стиле WPF/XAML. Когда создаёшь свой веб-компонент, там мешает Shadow DOM (инкапсуляция), чтобы добраться до двух тех полей https://learn.javascript.ru/shadow-dom это сделано для того, если у вас несколько веб-компонентов, там id будут дублироваться, а в HTML допустим id должны быть уникальными, поэтому они в ShadowRoot. т.е. неком ящике, в непроницаемой оболочки. Ну и ещё это защита.
ты невнимательно читал условия задачи.
-----
Я их вообще не читал - Я читал то что ты написал.
код нажатой клавиши + код дополнительной
-----
Если под "дополнительной" подразумевается ЦТРЛ,АЛТ,Шифт - все как написано выше.
Если подразумевается вторая цифро-буквенная - переставай пудрить мозги - ибо железо/клава не обрабатывает две одновременно нажатые клавиши этого типа.
Зачем только там так много менюшек?
Это стандартное меню, нужно так делать https://www.tutorialspoint.com/electron/electron_menus.htm
Зависит еще и от того как будет использоваться контрол, в простейшем случае можно сделать всё через его ViewModel.
адаптер (вьюмодел) для контрола - полный некошер. представьте себе окно с несколькими listview. вы что - к каждому из них отдельный адаптер (вьюмодед) лепите? я обычно - один адаптер на все окно (если не какие-то особые обстоятельства, которые не могу сразу придумать), и у него - пропертиз, к которым контролы из окна могут байндиться.
почему для юзэрьконтрола все должно быть иначе? должна быть выдержана концепция - контрол, которпый байндится к каким-то пропертям адаптера (дэйтэконтэкст), который как правило - один для всего окна.
имха такая. конечно, можно прилепить каждой клавише свой адаптер, свою команду, свое все на свете, и возиться с этим потом всю оставшуюся жизнь.
и говорить, что не любите говнокод ; )
зы. да, надеюсь, все новый год встретили хорошо, были и силы и желание принять водки и сьесть маринованый опенок : )
всем - здоровья и благополучия!
почему для юзэрьконтрола все должно быть иначе?
Предположим, у меня на одной странице 3 контрола, а на другой еще где-то еще такой же.
Или у меня таб контрол, на все страницы один VW? Хотя опять таки зависит от ситуации.
зы: вам тоже всего хорошего в Новом году
заморочка новая, но открывать новую тему, думаю, не обязательно (или было бы удобнее?)
вопрос. как в WPF изобразить массу кружочков, чтобы было "легковесно" и каждый можно было бы красить своим цветом и при первопоказе, и потом менять?
довольно быстро прорисовывается EllipseGeometry, но цвет у всех в группе один.
могу, конечно, на канве по битам распрашивать, но это - некошер, и не уверен, что будет быстрее.
в идеале - ссылка на примегчик.
спасибо, но гуглить сами могём : )
никаких "новых библигтек" или "технологий" изучать не предполагается.
просто ищу хороший пример, как можно массу EllipseGeometry (заявлено, как очень лайтуэйт) нарисовать так, чтобы каждая из них получала свой цвет. подозреваю, что их для этого нужно помещать в отдельные "контейнеры", цвета будут определяться для контейнеров. но меня бы это устроило.
скорее всего сделаю все с shape-объектами, и пусть себе перерисовывает сколько хочет. или буду сам пикселы вырисовывать.
что их для этого нужно помещать в отдельные "контейнеры"
мне так не кажется Но можно глянуть.
я уже упомянул: никаких библиотек, новых передовых технологий и пр. только элементарные частицы : )
вот создайте новый впф-проект и поместите в грид, созданный по умолчанию, это. затем попробуйте поиграться с Center="50,5", и попытайтесь мне пояснить, относительно чего эти координаты. и почему этот кружочек не по координате 50 (х), а вроде как 0?
<Border BorderBrush="Gray" BorderThickness="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Background="Transparent"> <Image Stretch="None" HorizontalAlignment="Left"> <Image.Source> <DrawingImage> <DrawingImage.Drawing> <GeometryDrawing> <GeometryDrawing.Geometry> <GeometryGroup> <EllipseGeometry Center="50,5" RadiusX="5" RadiusY="5" /> <EllipseGeometry Center="50,15" RadiusX="5" RadiusY="5" /> <EllipseGeometry Center="150,25" RadiusX="5" RadiusY="5" /> </GeometryGroup> </GeometryDrawing.Geometry> <GeometryDrawing.Brush> <SolidColorBrush Color="Blue" /> </GeometryDrawing.Brush> </GeometryDrawing> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> </Border>
ничего особо сложного не нашёл
Скорость не мерял, но работает
<ItemsControl ItemsSource="{Binding Items}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas Background="WhiteSmoke" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Canvas.Left" Value="{Binding X}"/> <Setter Property="Canvas.Top" Value="{Binding Y}"/> </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.ItemTemplate> <DataTemplate> <Path Fill="{Binding Color}"> <Path.Data> <EllipseGeometry RadiusX="{Binding Radius}" RadiusY="{Binding Radius}"/> </Path.Data> </Path> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
exe из архива не удалял.
и попытайтесь мне пояснить, относительно чего эти координаты
Там масштабирование относительно Image, с этой добавкой будет получше, но получить абсолютные координаты будет проблематично
<Image Stretch="None" HorizontalAlignment="Left" Width="800" Height="600">
Рекомендуют то по другому
https://docs.microsoft.com/en-us/dotnet/desktop/wpf/graphi...
Правда что за скорость нужна такая, так и не понял. Ну да ладно...
на экране - несколько тысяч кружочков, которые 2-3 раза в секунду (хорошо, раз в секунду) меняют свой цвет. пока цветов - три, диаметр кружочков - одинаков, двигать их пока не нужно, не знаю, понадобится ли.
попробуйте в вашей проге нагенерить хотя бы тысячу, установить таймер и менять цвет каждой ежесекундно. уверен, экран будет замерзать на несколько секунд. а если будет несколько тысяч? несколько дейстков тысяч? а если несколько раз в секунду?
попробуйте в вашей проге нагенерить хотя бы тысячу, установить таймер и менять цвет каждой ежесекундно
1000 и 0.1 достаточно? Вполне так себе шустренько. Не знаю получится ли 400кб видео загрузить..
Загрузить получилось, но не хочет в пост грузится, это только часть экрана, полная 7 Мб
хотите сказать, что показывает 10 "кадров" в секунду? я вижу иногда вообще какие-то непонятные (вернее, понятные : ) подвисания.
у меня (начальный этап) 10 000 кружочков, 0.5. попробовал интервал 0.1 сек - тоже очень флот все бежит, но мне это слишком быстро, еще не знаю, или секунду или половину.
зы а чем вы это кыдо сняли?
хотите сказать, что показывает 10 "кадров" в секунду?
Угу
а чем вы это кыдо сняли?
Давно уже прикупил https://www.techsmith.de/
Очень всем рекомендую. Доки делать просто удовольствие.
На 10 000 похуже будет, но еще юзабельно
Давно уже прикупил https://www.techsmith.de/Очень всем рекомендую. Доки делать просто удовольствие.
какой именно продукт, чтоб я не терял время?
уменьшите количество кружков до 100, оставьте паузу 0.1 сек. и посмотрите
Возможно я плохо тренирован, но разницы с 1000 не замечаю.
Нужно просто тогда измерить
кто платил?
Я прежде всего для дома купил, как и решарпер.
Да и надоело на каждом проекте кляньчить - купите, да купите. На одного то редко, что берут, если берут, то на всю команду сразу.
Девэкспресс или Деварт тоже вот давно хочу купить, но цена отпугивает.
ну вот, видите. а у меня их - не менее 10 тыщ, кроме того, вы только случайным образом цвета меняете, а я не калейдоскоп делаю, еще некая бизнес-логика должна когда-то выполниться, которая будет решать, каким цветом какой кружочек. это еще тоже предстоит.
уже подумывал снова с openGL соприкоснуться, но слава богу обошлось. уже не в том возрасте, чтобы ассемблеры новые нравилось осваивать. пару раз пришлось. с минизадачей в присутствии openGL справился,. закрыв глаза и с криком "ааааааа!!!!!!!!!!!!!!" как-то "запустил", и забыл как кошмарный сон.