196 / 41 / 24
Регистрация: 24.02.2013
Сообщений: 231
1
WPF

Не могу реализовать конвертер

29.07.2019, 14:01. Показов 3552. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В общем задача:
Есть коллекция ObservableCollection<string>, сейчас она привязана в XAML к ListBox. Все отлично.
Я хочу ее привязать к TextBox.
Реализовал конвертер:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DateTimeToDateConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (targetType != typeof(string))
                throw new InvalidOperationException("The target must be a String");
 
            return String.Join(", ", ((ObservableCollection<string>)value).ToArray());
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }
XAML
XML
1
<TextBlock Grid.Column="3" Text="{Binding Path=ListUsers,Converter={StaticResource Converter}}" />
Судя по отладке конвентер работает только при начальном запуске, далее когда коллекция заполняется точка останова уже не срабатывает.
C#
1
2
3
4
5
 public ObservableCollection<string> ListUsers
        {
        get { return _listUsers; }
        set { _listUsers = value; OnPropertyChanged(); }
        }
Я предполагаю, что метод Set не работает при изменении значений внутри коллекции?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.07.2019, 14:01
Ответы с готовыми решениями:

Реализовать конвертер XML-JSON
В общем, такое задание: Реализовать конвертер XML-JSON, JSON-XML Исходный файл XML: ...

Реализовать конвертер фунтов в килограммы
Помогите с кодом консольной программы ...

Реализовать конвертер денежных единиц
Устаревшая денежная система Великобритании состояла из фунтов, шиллингов и пенсов. Один фунт был...

Реализовать конвертер градусов по Фаренгейту в градусы по Цельсию (C++98)
Написать программу, которая получает данные по Фаренгейту и преобразует их в данные по Цельсию для...

8
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
29.07.2019, 14:08 2
alexSo94,

Я предполагаю, что метод Set не работает при изменении значений внутри коллекции?
конвертер сработает только при изменении коллекции, т.е. в случае срабатывания его settera, если же изменятся какие-нибудь элементы коллекции, конвертер не сработает.

Добавлено через 2 минуты
попробуйте там где вы изменяете элементы коллекции вызвать OnPropertyChanged(nameof(ListUsers));
1
196 / 41 / 24
Регистрация: 24.02.2013
Сообщений: 231
29.07.2019, 14:12  [ТС] 3
Цитата Сообщение от hamin Посмотреть сообщение
конвертер сработает только при изменении коллекции, т.е. в случае срабатывания его settera, если же изменятся какие-нибудь элементы коллекции, конвертер не сработает.
Я правильно понимаю, что нужно копать в сторону события CollectionChanged ?

Добавлено через 2 минуты
Цитата Сообщение от hamin Посмотреть сообщение
попробуйте там где вы изменяете элементы коллекции вызвать OnPropertyChanged(nameof(ListUsers));
Чуть не забыл использую паттерн MVVM. Заполняю коллекцию в модели
0
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
29.07.2019, 14:17 4
Лучший ответ Сообщение было отмечено alexSo94 как решение

Решение

даже если у вас будет коллекция элементов класса, который реализует INPC конвертер не сработает, т.к. вы привязываетесь непосредственно к коллекции

Добавлено через 4 минуты
alexSo94,

зачем вам вообще конвертер? сделайте свойство типа стринг, привяжите его где нужно и устанавливайте свойство непосредственно при изменении коллекции..

C#
1
2
3
4
5
6
7
8
9
10
11
12
public string MyValue 
{
    get { return _myValue; }
    set { _myValue = value; OnPropertyChanged(); }
}
 
 
private void PlaceWhereCollectionChanging()
{
     ListUsers[0] = "Hallo, world!";
     MyValue = String.Join(", ", ListUsers.ToArray());
}
XML
1
<TextBlock Grid.Column="3" Text="{Binding MyValue}" />
1
Модератор
Эксперт .NET
15569 / 10800 / 2805
Регистрация: 21.04.2018
Сообщений: 31,765
Записей в блоге: 2
29.07.2019, 14:19 5
Лучший ответ Сообщение было отмечено alexSo94 как решение

Решение

Цитата Сообщение от alexSo94 Посмотреть сообщение
конвентер работает только при начальном запуске
Обновление отображения значения свойств происходит по событию PropertyChanged. Оно возникает (в вашем случае) при замене коллекции в свойстве ListUsers.

При изменении самой коллекции возникает событие CollectionChanged на него подписываются только списочные элементы.

Самым простым решением будет создание свойства в VM для привязки TextBlock. Подписаться на событие CollectionChanged и при его возникновении пересчитывать значение для TextBlock.
1
196 / 41 / 24
Регистрация: 24.02.2013
Сообщений: 231
29.07.2019, 15:51  [ТС] 6
Спасибо
Создал новое свойство
C#
1
2
3
4
5
6
7
8
public string TextList
        {
            get { return textList; }
            set
            {
               textList= value; OnPropertyChanged();
            }
        }
Подписался на событие
C#
1
ListUsers.CollectionChanged += PlaceWhereCollectionChanging;
C#
1
2
3
4
5
6
7
private void PlaceWhereCollectionChanging(object sender, NotifyCollectionChangedEventArgs e)
        {
          foreach(var value in e.NewItems)
            {
                TextList += $"{value}\r\n";
            }
        }
1
Модератор
Эксперт .NET
15569 / 10800 / 2805
Регистрация: 21.04.2018
Сообщений: 31,765
Записей в блоге: 2
29.07.2019, 16:13 7
Цитата Сообщение от alexSo94 Посмотреть сообщение
Создал новое свойство.....
Подписался на событие....
Не знаю насколько нужно вам, но в такой реализации при удалении TextList продолжит отображать удалённые элементы.
1
196 / 41 / 24
Регистрация: 24.02.2013
Сообщений: 231
30.07.2019, 07:08  [ТС] 8
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Не знаю насколько нужно вам, но в такой реализации при удалении TextList продолжит отображать удалённые элементы.
Я правильно понимаю ?:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void PlaceWhereCollectionChanging(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (var item in e.OldItems)
                {
                   TextList.Remove(e.OldItems.IndexOf(item));
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (var item in e.NewItems)
                {
                    TextList += $"{item}\r\n";
                }
            }
        }
0
Модератор
Эксперт .NET
15569 / 10800 / 2805
Регистрация: 21.04.2018
Сообщений: 31,765
Записей в блоге: 2
30.07.2019, 10:24 9
Цитата Сообщение от alexSo94 Посмотреть сообщение
Я правильно понимаю ?:
Да, правильно.
Но, по-моему, проще сделать так
C#
1
2
3
4
         private void PlaceWhereCollectionChanging(object sender, NotifyCollectionChangedEventArgs e)
        {
            TextList = string.Join("\r\n", ListUsers) ;
        }
Метод string.Join() работает очень быстро. Если коллекция не очень большая, то проще через него сделать чем отслеживать добавление/удаление/вставку/перестановку элементов.
В большинстве случаем, до нескольких тысяч элементов string.Join() будет справляться без лагов.
1
30.07.2019, 10:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.07.2019, 10:24
Помогаю со студенческими работами здесь

Реализовать программу-конвертер валют с использованием конструкции switch
Помогите написать программу-конвертер валют, долларов, евро и фунтов стерлингов с использованием...

Реализовать конвертер оттенка цвета из формата RGB (кодированный тремя байтами) в формат HTML
Любой цвет можно определить компонентами r, g, b - красный, зеленый, синий. В зависимости от того,...

Реализовать программу "Конвертер величин измерения"
Написать программу для перевода единиц измерения например длины . Из: В: Миллиметры Миллиметры ...

Не могу открыть документ в ворд 2007: "не удалось запустить конвертер mswrd632"
не могу открыть документ ворд. &quot;Приложению Word не удалось запустить конвертер mswrd632&quot;. &lt;- как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru