Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
WPF

DataTrigger Binding для стиля DataGridCell к значению ячейки

28.10.2022, 08:38. Показов 2092. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Появилась необходимость написать стиль для ячейки DataGrid, который мог бы при определённом значении ячейки проводить некие действия с оформлением. Но возник вопрос - как правильно забиндить DataTrigger на значение этой ячейки, чтобы не писать этот стиль полностью в каждой нужной ячейке, а просто подключить его и всё...
Вот сам стиль, и хотелось бы его добавить в ресурсы
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<DataGridTextColumn Width="25*"
                    Binding="{Binding WUsefulLife, Converter={StaticResource DecimalNullableValueConverter}}"
                    HeaderStyle="{StaticResource HeaderCenter}"
                    ElementStyle="{StaticResource TextRight}">
    <DataGridTextColumn.Header>
        <TextBlock Text="Срок&#x0a;использования" TextAlignment="Center" Padding="0"/>
    </DataGridTextColumn.Header>
    <!-- Вот стиль, который нужно вынести в ресурсы -->
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <!-- Как вот тут сделать универсальный биндинг на значение ячейки, а не прямой на значение свойства? -->
                <DataTrigger Binding="{Binding WUsefulLife, Converter={StaticResource NullToBoolConverter}}"
                             Value="True">
                    <Setter Property="Background" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>
Спасибо!!!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.10.2022, 08:38
Ответы с готовыми решениями:

Как DataTrigger менять текст ячейки в DataGrid?
Хочу поменять &quot;забинженный&quot; текст и цвет текста в ячейке DataGrid в зависимости от значения в ячейке. Цвет меняется а текст остаётся...

Не работает Binding из стиля
Добрый день, у меня есть стиль, в нём лежит ControlTemplate, в нём есть Border, я добавил ему Binding на Visibility: &lt;Border...

Binding через RelativeSource в шаблоне для ячейки GridControl
Здравствуйте. Пытаюсь создать шаблон для ячейки GridControl, который можно будет использовать на нескольких столбцах. Столбцы биндятся на...

36
1596 / 601 / 185
Регистрация: 05.12.2015
Сообщений: 970
29.10.2022, 02:49
Студворк — интернет-сервис помощи студентам
По теме сделал похожее.
Уже поздно, потом напишу комменты.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   class ValueStyleX : StyleSelector
    {
        public static object GetStylex ( DependencyObject obj ) { return ( object ) obj.GetValue (StylexProperty); }
        public static void SetStylex ( DependencyObject obj, object value ) { obj.SetValue (StylexProperty, value); }
 
        public static readonly DependencyProperty StylexProperty = DependencyProperty.RegisterAttached ("Stylex", typeof (object), typeof (ValueStyleX), new PropertyMetadata (null));
 
        cellselector cellstyles = new cellselector ();
 
        public override Style SelectStyle ( object item, DependencyObject container )
        {
            if ( container is DataGridRow row )
                row.Loaded += delegate
                {
                    DataGridCellsPresenter present = row.GetType ().GetProperty ("CellsPresenter", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue (row) as DataGridCellsPresenter;
                    present.ItemContainerStyleSelector = cellstyles;
                };
            return base.SelectStyle (item, container);
        }
        class cellselector : StyleSelector
        {
            public override Style SelectStyle ( object item, DependencyObject container )
            {
                if ( container is DataGridCell cell )
                {
                    cell.Loaded += ( s, e ) =>
                    {
                        if ( s is DataGridCell dc )
                        {
                            object val = dc.DataContext.GetType ().GetProperty (( ( dc.Column as DataGridBoundColumn ).Binding as Binding ).Path.Path).GetValue (dc.DataContext);
                            SetStylex (dc, val);
                        }
                    };
                    cell.Unloaded += ( s, e ) => {SetStylex (s as DependencyObject, null); };
                }
                return base.SelectStyle (item, container);
            }
        }
    }
В ресурсах можно разные стили с разными триггерами
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.ItemContainerStyleSelector>
                <local:ValueStyleX/>
            </DataGrid.ItemContainerStyleSelector>
            <DataGrid.Resources>
                <Style x:Key="redKey" TargetType="DataGridCell">
                    <Setter Property="Background" Value="Yellow"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource self}, Path=(local:ValueStyleX.Stylex)}" Value="-1">
                            <Setter Property="Background" Value="Red"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" CellStyle="{StaticResource redKey}"/>
                <DataGridTextColumn Binding="{Binding Value}" CellStyle="{StaticResource redKey}"/>              
            </DataGrid.Columns>
        </DataGrid>
2
1596 / 601 / 185
Регистрация: 05.12.2015
Сообщений: 970
29.10.2022, 08:49
В коде строки с 30-31 заменить:
C#
1
2
             Binding bind = ( dc.Column as DataGridBoundColumn ).Binding as Binding;
             BindingOperations.SetBinding (dc, StylexProperty, bind);
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
29.10.2022, 12:00
Цитата Сообщение от proa33 Посмотреть сообщение
По теме сделал похожее.
Согласен.
Это действительно похоже. Правда не запускал - сужу по коду.

Но мне больше нравится расширение разметки.
Его удобнее в XAML использовать.

Добавлено через 5 минут
Цитата Сообщение от proa33 Посмотреть сообщение
В коде строки с 30-31 заменить:
Блин!!!
А я уже целый абзац написал по этому поводу!
Вы уже сами поправили.



Добавлено через 2 минуты
dc - это FrameworElement.
Поэтому привязку можно задать его методом: dc.SetBinding (StylexProperty, bind);.
0
1596 / 601 / 185
Регистрация: 05.12.2015
Сообщений: 970
29.10.2022, 13:42
можно дополнить чтоб упростить разметку
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 class ValueStyleX : StyleSelector
    {
        public static object GetStylex ( DependencyObject obj ) { return obj.GetValue (StylexProperty); }
        public static void SetStylex ( DependencyObject obj, object value ) { obj.SetValue (StylexProperty, value); }
 
        public static readonly DependencyProperty StylexProperty = DependencyProperty.RegisterAttached ("Stylex", typeof (object), typeof (ValueStyleX), new PropertyMetadata (null));
        public static bool? GetIsAdd ( DependencyObject obj ) { return ( bool? ) obj.GetValue (IsAddProperty); }
        public static void SetIsAdd ( DependencyObject obj, bool? value ) { obj.SetValue (IsAddProperty, value); }
        public static readonly DependencyProperty IsAddProperty = DependencyProperty.RegisterAttached ("IsAdd", typeof (bool?), typeof (ValueStyleX), new PropertyMetadata (null, changed));
        private static void changed ( DependencyObject d, DependencyPropertyChangedEventArgs e )
        {
            if ( d is DataTrigger trigg )
                if ( GetIsAdd (trigg) == true )
                    trigg.Binding = new Binding ()
                    {
                        RelativeSource = new RelativeSource (RelativeSourceMode.Self),
                        Path = new PropertyPath ("(0)", StylexProperty)
                    };
                else
                    trigg.Binding = new Binding ();
        }
 
        cellselector cellstyles = new cellselector ();
        public override Style SelectStyle ( object item, DependencyObject container )
        {
            if ( container is DataGridRow row ) //загрузка DataGridRow
                row.Loaded += delegate          // ожидаем пока загрузится шаблон
                {
                    DataGridCellsPresenter present = row.GetType ().GetProperty ("CellsPresenter", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue (row) as DataGridCellsPresenter;
                    if ( present != null ) // нашли контейнер для DataGridCell
                        present.ItemContainerStyleSelector = cellstyles; // генератор каждой Cell
                };
            return base.SelectStyle (item, container);
        }
        class cellselector : StyleSelector // генератор одной DataGridCell
        {
            public override Style SelectStyle ( object item, DependencyObject container )
            {
                if ( container is DataGridCell cell ) // получили контейнер ячейки
                {
                    cell.Loaded += ( s, e ) => // ожидание загрузки всех полей. Надо получить Column, который пока null
                    {
                        if ( s is DataGridCell dcell ) // Column получен
                        {                            
                            Binding bind = ( dcell.Column as DataGridBoundColumn ).Binding as Binding;
                            dcell.SetBinding (StylexProperty, bind);
                        }
                    };
                    cell.Unloaded += ( dc, e ) => { ( dc as DataGridCell ).ClearValue (StylexProperty); };
                }
                return base.SelectStyle (item, container);
            }
        }
    }
тогда триггеры будут такие:
XML
1
2
3
          <DataTrigger local:ValueStyleX.IsAdd="True" Value="-1">
                 <Setter Property="Background" Value="Green"/>
          </DataTrigger>
еще решить вопрос с ненужными присвоениями, там где нет стиля.
Надо еще одно АР на DataGridColumn чтоб присвоения были только для клеток из этого Column, где установлено это АР
2
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 09:16  [ТС]
Элд Хасп, proa33, Необходимость такого стиля возникла в ходе написания окна предпросмотра данных перед загрузкой в БД (скрин). То бишь если значение ячейки NULL - то цвет её фона должен меняться, крася красным нужные поля документа для экспорта.
Миниатюры
DataTrigger Binding для стиля DataGridCell к значению ячейки  
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 09:17  [ТС]
Ваши варианты еще пока не пробовал...
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 10:33
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Необходимость такого стиля возникла ....
Ну, то есть я прав, что стиль всех ячеек одинаковый?

И получение значения привязки ячейки позволяет создать такой общий стиль для всех ячеек?
0
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 10:41  [ТС]
Элд Хасп, Да, всё верно, стиль один.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 10:59
Andrey-MSK, ещё немного рефакторинга: DataGridCellValue.7z

И вариант для получения контента ячейки: DataGridCellContent.7z
В колонках DataGridBoundColumn это будет UI элемент ячейки.
Тоже может где-то пригодиться.
1
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 11:43  [ТС]
Элд Хасп, Вот так не работает
XML
1
2
3
4
5
6
7
8
9
10
<DataGridTextColumn.CellStyle>
    <Style TargetType="DataGridCell">
        <Style.Triggers>
            <DataTrigger Binding="{services:DataGridCellValue}"
                         Value="Null">
                <Setter Property="Background" Value="Red"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGridTextColumn.CellStyle>
А если пытаюсь подключить конвертер
XML
1
2
3
4
5
6
7
8
9
10
<DataGridTextColumn.CellStyle>
    <Style TargetType="DataGridCell">
        <Style.Triggers>
            <DataTrigger Binding="{services:DataGridCellValue, Converter={StaticResource NullToBoolConverter}}"
                         Value="True">
                <Setter Property="Background" Value="Red"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataGridTextColumn.CellStyle>
Выдаёт ошибку что конвертер не доступен, в выпадающем списке его нет, и еще пишет что-то про запятую после привязки, типа её там быть не должно...
Переписал ваш пример вот так, по стандарту C# 7.3
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
 
namespace HRClient.Services
{
    public class DataGridCellValue : MultiBinding
    {
        #region Attached Property
 
        /// <summary>Возвращает значение присоединённого свойства CellValue для <paramref name="cell"/>.</summary>
        /// <param name="cell"><see cref="DataGridCell"/> значение свойства которого будет возвращено.</param>
        /// <returns><see cref="object"/> значение свойства.</returns>
        public static object GetCellValue(DataGridCell cell)
        {
            return cell.GetValue(CellValueProperty);
        }
 
        /// <summary>Задаёт значение присоединённого свойства CellValue для <paramref name="cell"/>.</summary>
        /// <param name="cell"><see cref="DataGridCell"/> значение свойства которого будет возвращено.</param>
        /// <param name="value"><see cref="object"/> значение для свойства.</param>
        public static void SetCellValue(DataGridCell cell, object value)
        {
            cell.SetValue(CellValueProperty, value);
        }
 
        #endregion
 
        #region
 
        public DataGridCellValue()
        {
            Converter = cellValueConverter;
            Bindings.Add(cellSelf);
            Bindings.Add(cellColumn);
            Bindings.Add(cellAPValue);
            Bindings.Add(cellDataContext);
        }
 
        #endregion
 
        #region Converter
 
        private class CellValueConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                if (!(values[0] is DataGridCell cell) ||
                    !(cell.Column is DataGridBoundColumn))
                {
                    return DependencyProperty.UnsetValue;
                }
 
                if (!(values[1] is BindingBase columnBinding))
                {
                    return DependencyProperty.UnsetValue;
                }
 
                if (BindingOperations.GetBindingBase(cell, CellValueProperty) != columnBinding)
                {
                    cell.SetBinding(CellValueProperty, columnBinding);
                    return Binding.DoNothing;
                }
 
                return values[2];
            }
 
            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
 
        #endregion
 
        #region Static fields
 
        /// <summary><see cref="DependencyProperty"/> для методов <see cref="GetCellValue(DataGridCell)"/> 
        /// и <see cref="SetCellValue(DataGridCell, object)"/>.</summary>
        public static readonly DependencyProperty CellValueProperty =
            DependencyProperty.RegisterAttached(
                nameof(GetCellValue).Substring(3),
                typeof(object),
                typeof(DataGridCellValue),
                new PropertyMetadata(null, (d, _) =>
                { { if (!(d is DataGridCell)) throw new NotImplementedException("Реализовано только для DataGridCell"); } }));
 
        private static readonly Binding cellSelf = new Binding()
        {
            RelativeSource = RelativeSource.Self
        };
 
        private static readonly Binding cellColumn = new Binding()
        {
            RelativeSource = RelativeSource.Self,
            Path = new PropertyPath("(0).(1)", DataGridCell.ColumnProperty,
                                               typeof(DataGridBoundColumn).GetProperty(nameof(DataGridBoundColumn.Binding)))
        };
 
        private static readonly Binding cellAPValue = new Binding()
        {
            RelativeSource = RelativeSource.Self,
            Path = new PropertyPath(CellValueProperty)
        };
 
        private static readonly Binding cellDataContext = new Binding();
 
        private static readonly CellValueConverter cellValueConverter = new CellValueConverter();
 
        #endregion
    }
}
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 13:39
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Вот так не работает
Строка "Null" не есть null.
XML
4
5
            <DataTrigger Binding="{services:DataGridCellValue}"
                         Value="{x:Null}">
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
А если пытаюсь подключить конвертер
Свойство Конвертер биндинга уже занято:
C#
35
            Converter = cellValueConverter;
Подключить два конвертера в одно свойство не возможно, но можно передать второй конвертер через параметр:
C#
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
            private class CellValueConverter : IMultiValueConverter
            {
                public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
                {
                    if (values[0] is not DataGridCell cell ||
                        cell.Column is not DataGridBoundColumn)
                        return DependencyProperty.UnsetValue;
 
                    if (values[1] is not BindingBase columnBinding)
                        return DependencyProperty.UnsetValue;
 
                    if (BindingOperations.GetBindingBase(cell, CellValueProperty) != columnBinding)
                    {
                        cell.SetBinding(CellValueProperty, columnBinding);
                        return Binding.DoNothing;
                    }
 
                    object value = values[2];
 
                    return parameter is IValueConverter converter 
                        ? converter.Convert(value, targetType, null, culture) 
                        : value;
                }
XML
4
5
            <DataTrigger Binding="{services:DataGridCellValue ConverterParameter={StaticResource NullToBoolConverter}}"
                         Value="True">
Добавлено через 4 минуты
Ещё, возможно стоит изменить возврат после задания привязки AP-свойству.
Так как null - это дефолтное значение, то после присвоения привязки к null вызова конвертера не будет происходить.
Поэтому, возможно, надо так:
C#
24
25
26
27
28
29
    if (BindingOperations.GetBindingBase(cell, CellValueProperty) != columnBinding)
    {
        cell.SetBinding(CellValueProperty, columnBinding);
        //return Binding.DoNothing;
        return null;
    }
Добавлено через 1 минуту
Не... вот так - надо же ещё через доп. конвертер пропустить:
C#
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
            private class CellValueConverter : IMultiValueConverter
            {
                public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
                {
                    if (values[0] is not DataGridCell cell ||
                        cell.Column is not DataGridBoundColumn)
                        return DependencyProperty.UnsetValue;
 
                    if (values[1] is not BindingBase columnBinding)
                        return DependencyProperty.UnsetValue;
 
                    object value = null;
                    if (BindingOperations.GetBindingBase(cell, CellValueProperty) != columnBinding)
                    {
                        cell.SetBinding(CellValueProperty, columnBinding);
                        //return Binding.DoNothing;
                    }
                    else
                    {
                        value = values[2];
                    }
 
                    return parameter is IValueConverter converter
                        ? converter.Convert(value, targetType, null, culture)
                        : value;
                }
 
                public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
                {
                    throw new NotImplementedException();
                }
            }
Добавлено через 11 минут
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
{StaticResource NullToBoolConverter}
Не ленитесь делать расширение разметки для конвертеров.
Это значительно упрощает их использование в XAML.

Вот "рыба" под конвертер:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    [ValueConversion(typeof(object), typeof(bool))]
    public class NullToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
 
        // Если нет членов экземпляра, то нет и смысла в конструкторе экземпляра.
        private NullToBoolConverter() { }
 
        public static NullToBoolConverter Instance { get; } = new();
    }
 
    [MarkupExtensionReturnType(typeof(NullToBoolConverter))]
    public class NullToBoolExtension : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return NullToBoolConverter.Instance;
        }
    }
И использование с такой реализацией ConverterParameter={cnvs:NullToBool}.
В ресурсах создавать конвертер уже не нужно.
1
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 14:42  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Не... вот так - надо же ещё через доп. конвертер пропустить:
Опять ошибка в биндинге...
Code
1
Error   XDG0055 The character "," is unexpected at this position.
Вот тут, подсвечивает B в слове Binding
XML
1
2
<DataTrigger Binding="{services:DataGridCellValue, ConverterParameter={StaticResource NullToBoolConverter}}"
             Value="True">
Добавлено через 3 минуты
Элд Хасп, Конвертер вот такой
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Globalization;
using System.Windows.Data;
 
namespace HRClient.Converters
{
    public class NullToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return true;
            }
 
            return false;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
Может надо его как-то изменить? Не считая вашу рыбу...
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 15:01
Лучший ответ Сообщение было отмечено Andrey-MSK как решение

Решение

Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Вот тут, подсвечивает B в слове Binding
Там же лишняя запятая.
Запятой отделяются параметры. А у вас только один параметр. Она не нужна.

В же не пишите в методе SomeMethod(, args).
Так же и в XAML Расширении разметки.
1
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 15:04  [ТС]
Элд Хасп, Работает Во я слепой, у вас ведь было написано без запятой
Спасибо!!!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 15:08
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Конвертер вот такой
Зачем булл проверять ифом и его же возвращать?

C#
9
10
11
12
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value is null;
        }
Добавлено через 1 минуту
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Во я слепой,
Да, такие ошибки у всех бывают.
Особенно когда много сидишь за кодом, ищешь ошибки в чём-то сложном и упускаешь элементарное, лежащее под носом.

Добавлено через 1 минуту
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Работает
А без конвертера не попробовали?
XML
4
5
            <DataTrigger Binding="{services:DataGridCellValue}"
                         Value="{x:Null}">
1
 Аватар для Andrey-MSK
3397 / 2283 / 388
Регистрация: 14.08.2018
Сообщений: 7,765
Записей в блоге: 4
31.10.2022, 15:24  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А без конвертера не попробовали?
Так тоже вроде работает, по крайней мере на первый взгляд Но оставлю с конвертером
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
31.10.2022, 15:51
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Но оставлю с конвертером
Тогда хоть нормальный конвертер реализуйте.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
 
namespace CommonCore.AttachedProperties
{
    public enum NullToBoolEnum { NullTrue, NullFalse };
    [ValueConversion(typeof(object), typeof(bool))]
    public class NullToBoolConverter : IValueConverter
    {
        private readonly bool nullTrue;
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value is null == nullTrue;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
 
        // Если нет членов экземпляра, то нет и смысла в конструкторе экземпляра.
        private NullToBoolConverter(bool nullTrue) => this.nullTrue = nullTrue;
 
        public static NullToBoolConverter InstanceNullTrue { get; } = new(true);
        public static NullToBoolConverter InstanceNullFalse { get; } = new(false);
    }
 
    [MarkupExtensionReturnType(typeof(NullToBoolConverter))]
    public class NullToBoolExtension : MarkupExtension
    {
        public NullToBoolEnum IsNull { get; set; }
 
        public NullToBoolExtension(NullToBoolEnum isTrue)
        {
            IsNull = isTrue;
        }
 
        public NullToBoolExtension()
            : this(NullToBoolEnum.NullTrue)
        { }
 
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
 
            return IsNull switch
            {
                NullToBoolEnum.NullTrue => NullToBoolConverter.InstanceNullTrue,
                NullToBoolEnum.NullFalse => NullToBoolConverter.InstanceNullFalse,
                _ => throw new InvalidCastException($"Неожидаемое значение свойства {nameof(IsNull)}.")
            };
        }
    }
}
XML
1
2
3
4
<DataTrigger Binding="{services:DataGridCellValue ConverterParameter={cnvs:NullToBool}}"
             Value="True">
<DataTrigger Binding="{services:DataGridCellValue ConverterParameter={cnvs:NullToBool NullFalse}}"
             Value="True">
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
31.10.2022, 15:51

Привязка цвета ячейки к значению другой ячейки
Здравствуйте! Буду очень признателен, если кто-нибудь поможет разобраться с нависшей проблемой по экселю, суть которой в следующем: ...

Добавить текстовую строку к уже имеющемуся значению Binding
Добрый день джентльмены. Новичок в WPF. Такая ситуация: есть два TextBox - один источник Binding, другой приемник, все хорошо, только нужно...

Не выходит правильно сделать binding свойства к значению переменной класса
Пишу приложение, которое во время работы добавляет данные в лист который использует свой DataTemplate. Нужно привязать ширину обьекта...

Изменение стиля ячейки Datagridview
Подскажите, почему не получается изменить оформление границ Datagridview: DataGridViewAdvancedBorderStyle style=new...

Создание стиля ссылки для стиля
Известно как создать стиль ссылки для всего документа (который применяется если убрать форматирование): изменить стиль с названием...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru