154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
||||||
1 | ||||||
WPF Установка Control.Style не триггерит set функционал у свойства класса21.05.2019, 12:59. Показов 3281. Ответов 33
Всем привет.
У меня есть класс - CoordinateView (клеточка). Он экстендит класс Grid. Также в нём есть два поля - TextBlock и Rectangle. Они добавлены в этот класс как его Children. Первый преднозначен для того чтобы показывать текст, другой нужен чтобы устанавливать цвет и толщину рамок . То есть, задача этой структуры - иметь рамки, цвет и текст. (Если есть такой control по дефолту, дайте знать, я не нашёл, и сделал вот Grid с TextBlock и Rectangle в качестве его "детей", но вопрос пока не в этом). Далее, я хочу установить свойства этой моей клеточке. Всякие разные, один из которых, например, Margin. Но хочу это делать динамично. Поэтому использую свойство Style и создаю объект из вне и добавляю в него Setter'ы того, что мне нужно. И всё работает. Всё, чётенько и классненько. Почти. В основном свойства, которые я устанавливаю относятся именно к классу Grid. Но вот есть несколько значений свойств, которые мне нужно передать "детям" (TextBlock и Rectangle), например Label и StrokeThickness. Эти два поля у меня приватные, я не хочу из вне чтобы был доступ к ним. Поэтому я создал wrapping свойства в классе своей клеточки в которых устанавливаю значения "детям". Получается вот так:
Вопрос: как сделать так, чтобы rectangle.Stroke всё-таки получал это значение, когда я устанавливаю стиль моей клеточки. Заранее спасибо!
0
|
21.05.2019, 12:59 | |
Ответы с готовыми решениями:
33
Работа свойства Bottom класса Control Выполнить команду в set свойства для свойства SelectedItem (ComboBox ) MVVM Как дополнить функционал класса из другого класса Свойства get и set |
Модератор
|
|||||||||||
21.05.2019, 13:37 | 2 | ||||||||||
Сообщение было отмечено Элд Хасп как решение
Решение
Какой-то сложный вариант Вы выбрали.
А такая реализация UC Вам не подойдёт? CB
1
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
21.05.2019, 14:01 [ТС] | 3 |
Блин, круто! Идея ясна. Мне стоит поизучать XAML, а то я им пренебрегаю ввиду незнания.
Хорошо, я полагаю будет значение передаваться в TextBlock, когда мы будем устанавливать значение Text в borderTextBlock. А будет ли это работать (смогу вечером протестировать только), если сделаю borderTextBlock.Style = style, если в style будет Setter с TextProperty? У меня проблема именно в этом.
0
|
Модератор
|
||||||
21.05.2019, 14:14 | 4 | |||||
Не понял, что Вы хотите сделать.
При использовании UC в View Вы хотите в стиле этого UC обратиться к его свойству Text (которое было добавлено)? Если да, то работать будет без каких либо проблем. Изучать XAML нужно ОБЯЗАТЕЛЬНО. Это основной язык для создания WPF View. Только когда его возможностей не хватает, стоит использовать другие языки (в основном C#). Но то что сделано в XAML полностью можно повторить и в CB на C#. Суть в другом. Вы обращаетесь DP-свойствами как с CLR-свойствами. А в данном случае вместо
Мне проще это сделать в XAML - там конструктор сам создаёт привязки. Просто выбираешь где, какую привязку надо сделать, а весь код вставляет конструктор. В CB это всё надо делать "ручками".
1
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
21.05.2019, 14:20 [ТС] | 5 |
Всё понял. Буду изучать (С WPF играюсь чисто для себя, поэтому чайник на данный момент). Вечером реализую и отпишусь. А пока что большое спасибо Вам.
P. S. не по теме, но может быть Вы могли бы порекомендовать литературу по WPF c XAML? Я, конечно, могу выбрать вслепую, но мне интересно Ваше мнение.
0
|
Модератор
|
||||||
21.05.2019, 14:48 | 6 | |||||
Сообщение было отмечено Элд Хасп как решение
Решение
Тоже самое но чисто в на C#.
Не тестировал - возможно есть ошибки.
Книги ни какие не читал. В основном читал web ресурсы: METANIT, professorWeb, документацию doc.microsoft. Совсем в самом начале сморел несколько курсов по YouTube.
1
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
21.05.2019, 23:49 [ТС] | 7 |
Работает! Спасибо большое! Я счастлив
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|||||||||||||||||||||||||||||||
27.05.2019, 22:46 [ТС] | 8 | ||||||||||||||||||||||||||||||
Элд Хасп,
Привет ещё разочек. У меня возникла ещё одна проблемка. Думал, создать новую тему, но тема всё-таки остаётся той же, поэтому пишу сюда. Проблема заключается в том, что binding не работает. Теперь на этот раз между свойствами Style и Style классов View (CoordinateView) и View Model (CoordinateViewModel). View:
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
28.05.2019, 00:01 [ТС] | 10 |
Ну как же так? Вот же он (под View Model проскроллить надо вниз код):
0
|
Модератор
|
||||||
28.05.2019, 00:10 | 11 | |||||
Да, не проскролил.
Я посмотрел Вашу реализацию свойства Style и увидел, что оно реализовано как CLR свойство. Поэтому дальше и не смотрел - это значения не имеет. Свяжите его с DependencyProperty StyleProperty .Они должны работать как единое целое. Скорее всего дело именно в этом. Добавлено через 2 минуты
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
28.05.2019, 00:19 [ТС] | 12 |
Извините, но мой класс ViewModel не есть FrameworkElement. Я не могу вызвать GetValue в нём.
У меня вот какая цель. Я создал view (клеточка) и view model. Хочу их забиндить между собой. Во второй будет находиться логика, в зависимости от которой будет меняться свойство style. Всё, что мне хотелось бы, чтобы это свойство автоматом бы передавалось в мой view (клеточку).
0
|
Модератор
|
||||||
28.05.2019, 00:34 | 13 | |||||
Класс в котором находится
DependencyProperty свойство должен наследоваться от DependencyObject . Без этого Вы не можете создать полноценное DP-свойство.Если Вам надо привязать к CLR свойству, то в привязке и указывайте название CLR свойства.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
||||||||||||||||
28.05.2019, 00:48 [ТС] | 14 | |||||||||||||||
В viewModelBase сделал вот так:
P. S. Ещё до всего этого менял binding.path на clr всё равно не работало. Когда открыл новый проект и сделал тоже самое с полем типа string - всё работало. Может Style какой-то исключительный тип? Ну или я сам исключительный тип ввиду кривых рук.
0
|
Модератор
|
|
28.05.2019, 00:59 | 15 |
Pro100Tom, у меня нет практики создания привязок в коде.
Кроме как в этой теме не делал ни когда. Надо пробовать и проверять. Вы в дебагере проверяли саму привязку? Значения после изменений? Попробуйте в интерпретаторе создавать привязку и проверять её значение. Реализовать в XAML. Что Вы собственно реализуете? Что за решение? Как-то Вы через чур сложным путём идёте. Верно ли Вы выбрали путь реализации?
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
28.05.2019, 01:52 [ТС] | 16 |
Конечно, всё проверял. Говорю же, отдельный проект создал чтобы протестировать на более простом варианте. В xaml не могу реализовать, у меня там пару значений в стиле должны быть высчитаны в run-time.
Смотрите, пишу игру battleship. Есть клеточки, у каждой свой стиль. Если мы наводим мышкой, то меняем цвет. Если жмём по клеточке, снова меняем цвет. Когда произошёл клик, хочу содать command, который тригеррил бы функцию в соответствующей view model, там будет происходить логика мол есть ли на поле боя корабль в этой клетке. Если есть, то устанавливаем стиль себе (во view model), а этот стиль автоматом забиндин будет с полем стиля самой клеточки. Например, если на этой клетке есть корабль, то после клика, она меняет цвет. Добавлено через 41 минуту Разобрался. Там была проблема не в биндинге, а в свойстве класса стиля. Сорри за винегрет, всё работает.
0
|
Модератор
|
|
28.05.2019, 10:52 | 17 |
Если можете покажите и объясните решение.
На мой взгляд у Вас путаница между данными и их отображением. То как Вы делаете, ещё допустимо для какого-то графического редактора, где отображение самих элементов и является источником данных. Но для морского боя..... Данные здесь - это чисто CLR классы. Зачем здесь все эти манипуляции... Очень большая вероятность, что Вы неверно спроектировали приложение, отсюда и такие неспецифические для WPF проблемы. Прочитайте Морской бой В теме я начал проектировать Морской Бой, но TC перестал отвечать - поэтому не завершил.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
28.05.2019, 19:55 [ТС] | 18 |
На самом деле, я толком не разобрался почему та реализация вызывала именно такой результат. Я погляжу еще вечерком, как дома буду. Но я там быстренько просто в конструктере класса стиля создаю стили и кидаю их в его свойство, а потом уже присваиваю его свойство свойству моей viewModel. Так не работало, но зато заработало, когда я не использовал никаких свойств в своём классе стиля и просто создал функцию, в которой возвращается новый экземпляр класса Style, тогда всё заработало. Естественно я всё почищу ибо как раз пишу эту игру для того чтобы поиграться именно с архитектурой.
Вообще для меня архитектура важна сильнее всего. Я работаю в eCommerce и ненароком знаю о важности extensibility и flexibility в коде, а так же reusability. Поэтому я реально ломаю голову по поводу решения. Я не тупо выбираю архитектуру по книгам, а вырисовываю решения в голове потенциальных проблем. Поэтому, когда Вы мне говорите, что я нагромождаю, то мне хотелось бы услышать Вашу альтернативу. Смотрите. С чем мне связать стиль класса coordinateView? С моделью координаты не могу. Она имеет только поля row и column. Я не хочу добавлять туда поля типа hasShip, wasChecked потому что эти вещички добавляют зависимость от других классов. Может связать клеточку с моделью корабля? Ведь, если корабль был ранен или убит, мы сможем понять, что цвет клеточки должен изменяться. Но а где мне тогда доставать нужный сет стилей для клеточки, корабль на которой был подбит? И ещё, если несколько клеточек связаны с одним кораблем, то я уже не могу изменить одну из этих клеточек отдельно, если свойство корабля изменится, а это минус. Я вообще не хотел использовать биндинги. Я выбрал WPF потому что у него крутые controls. А язык выбрал потому что просто люблю C# и окна. Хотя лабиринт я пишу на C++ и 3D графику тоже писал на C++. Так вот, я тут понюхал про viewModels и понял, в чём заключается их принцип (наверное). Я связываю этот viewModel с coordinateView и уже из viewModel использую различные сервисы (модели) которые там определяют есть ли корбаль на этоё клетки или нет, ранен ли он, если есть и в зависимости от этого результата "возвращает" нужный стиль моей клеточке, которая будет его использовать. Вообще, я хочу создать сэт стилей для каждого случая (есть корабль, ранен ли он или убит), в котором есть стили трёх states: idle, mouseOver, mouseDown. По-моему прикольно, ибо я могу менять всё что угодно, когда навожу мышку на поле врага; скажем, поменяется цвет (типа хайлайт). Нажимаю мышкой, label отображает знак вопроса, мол типа есть ли тут корабль. А если попал, то отображает крестик. Также меняется цвет и всё это по-моему здорово. Скажите мне, как тут можно упростить и улучшить архитектуру и я с удовольствием к Вам прислушаюсь ибо пишу это всё для того чтобы стать лучше. P. S. Книги Роберта Мартина и Dessign Patterns by Gang of Four конечно же прочитал. В общем, заранее спасибо. P. P. S. А вообще желательно бы было связать интерфейс класса viewModel с моей клеточкой, а потом уже иметь возможность полиморфить этот класс как угодно в различных компонентах так чтобы базовые остались стабильными.
0
|
Модератор
|
|
28.05.2019, 22:23 | 19 |
Ну, если разберётесь - напишите.
Я привязки в коде C# не создаю. Но знания лишними не бывают. Привязки - это самое главное нововведение в WPF (по сравнению с WF). В современном программировании принято разделять данные и их отображение. Основным паттерном для WPF является MVVM. Фактически WPF специально под этот паттерн и создавался для реализации View (Представление). В MVVM за обработку данных отвечает Model (Модель). Модель работает полностью независимо от других частей приложения. Её работа не зависит от того где она выполняется: на локальном компе, на сервере, на WEB сервере и т.д. Модель ни как не связана с представлением. Представление для визуализации данных может быть любым WPF, WF, консоль и любое другое. Вот теперь подумайте. Если View - это консоль. А обработка данных (кораблей, палуб) у Вас завязана на стиль. От куда в консоли стиль? То есть Вы фактически используете визуальные свойства элементов как данные. Как я писал выше, такое допустимо для какого-то графического приложения. Но ни как ни для игры "Морской бой". Примерно как начать реализацию Модели я уже Вам дал ссылку. Модель - это первое что должно быть создано в WPF приложении. View создаётся позже. У Вас же Модели, вообще, нет. Из-за этого многочисленные неспецифические проблемы. Если делать нормально (то есть сначала Model, потом View и напоследок ViewModel), то я думаю Ваше приложение можно сделать за несколько часов. MVVM - Это ни какой-то "заговор" программистов. Это паттерн придуманный для значительного облегчения создания приложения. Так как он используется практически всеми, то код приложения становится читаемым, шаблонным, понятным. Соответственно для такого кода есть множество шаблонных решений. Можно ли создавать WPF приложения вне MVVM? Это подобно "удалению гланд через задницу". Конечно, можно. Но это очень трудно. ОЧЕНЬ - это в десятки раз. Здесь в разделе есть несколько тем где я показывал как шаг за шагом надо реализовывать WPF приложение. Хотите научить - по возможности помогу. Прочитайте темы в разделе Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп] Склейщик фото (создание MVVM приложения) Суммирование элементов в 2048 Что не понятно интересуйтесь прямо в темах. Когда разберётесь - можно так же шаг за шагом реализовать и Ваше приложение.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 397
|
|
29.05.2019, 00:53 [ТС] | 20 |
Спасибо за ответ и да, я знаю о ролях этих компонентов.
У меня вопрос по следующему комментарию: У меня есть модель. Она возвращает (во viewModel) мне значение (мимо, ранил, убил), и тот уже "высылает" (биндингом) нужный стиль для моей клеточки. Тут Вы говорите про консоль как вид, чтобы я подумал про разделение. Правильно ли я понимаю, что для каждого вида нужен свой viewModel? Если так, то я не вижу ошибки в своей архитектуре. Мы создаём консоль, создаем viewModel для неё и вызываем ту же модель, которая возвращает "мимо/ранил/убил" и viewModel уже решает что там надо возвращать окну. Что в моей реализации не так-то? MVC, (теперь и чуть-чуть MVVM) мне знакомы, и я хорошо понимаю, что касается модели, а что нет, ибо в данном случае как раз после промаха игрока пойдёт выстрел AI, а ему вид вообще не нужен. За литературу спасибо, я обязательно всё изучу. И начну вот в поезде на работу завтра.
0
|
29.05.2019, 00:53 | |
29.05.2019, 00:53 | |
Помогаю со студенческими работами здесь
20
свойства get;set; Свойства set get Свойства get set Биндинг свойства контрола к одной из переменных свойства класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |