Как установить значение привязки для свойства TargetNullValue в DataGridTextColumn WPF XAML

Я пытаюсь установить значение по умолчанию в свой DataGridTextColumn в случае, если свойство привязки дает нулевое значение, например, и если на сервере sql ...

Итак, я исследовал и нашел свойство TargetNullValue, где я могу указать значение по умолчанию, если столбец имеет значение NULL.

Но не работает, как я. Выдает мне следующую ошибку

System.Windows.Markup.XamlParseException: 'Привязка' не может быть установлена ​​для свойства 'TargetNullValue' типа 'Binding'. «Привязка» может быть установлена ​​только для свойства DependencyProperty объекта DependencyObject.

Вот пример моего кода XAML.

<DataGrid x:Name = "proveedorDataGrid" AutoGenerateColumns = "False" EnableRowVirtualization = "True" ItemsSource = "{Binding IsAsync=True}" Margin = "15,50,25,70" RowDetailsVisibilityMode = "VisibleWhenSelected"
              SelectionMode = "Single" IsReadOnly = "True" CanUserAddRows = "False" CanUserResizeRows = "False" CanUserDeleteRows = "False" PreviewKeyDown = "ProveedorDataGrid_OnPreviewKeyDown">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name = "municipioColumn" Binding = "{Binding Municipio, TargetNullValue = {Binding CCodigoPostal.Municipio}}" Header = "Municipio" Width = "Auto" />
        </DataGrid.Columns>
    </DataGrid>

с текущими ресурсами

<Window.Resources>
    <CollectionViewSource x:Key = "proveedorViewSource" d:DesignSource = "{d:DesignInstance {x:Type Core:Proveedor}, CreateList=True}"/>
</Window.Resources>

Фактически привязан к EntityFramework с использованием DataSource ...

Огромное спасибо заранее!

* Обновлен КЛАСС

public class Proveedor
{
    public Proveedor()
    {
        ValeVehiculoCombustibles = new HashSet<ValeVehiculoCombustible>();
        FacturaProveedors = new HashSet<FacturaProveedor>();
        EntradaBasculas = new HashSet<EntradaBascula>();
    }

    public Guid? Id_Proveedor { get; set; }

    public string Codigo { get; set; }

    public string RazonSocial { get; set; }

    public string Calle { get; set; }

    public string Colonia { get; set; }

    public virtual C_CodigoPostal CCodigoPostal { get; set; }
    public int CCodigoPostalId { get; set; }

    public string Telefonos { get; set; }

    public string RFC { get; set; }

    public virtual CuentaContable CuentaContable { get; set; }
    public Guid? CuentaContableId { get; set; }

    public short DiasCred { get; set; }

    public decimal SaldoMN { get; set; }

    public decimal AnticipoMN { get; set; }

    public decimal SaldoDlls { get; set; }

    public decimal AnticipoDlls { get; set; }

    public string Contacto { get; set; }

    public string Email { get; set; }

    public string Municipio { get; set; }

    public string Estado { get; set; }

    public string Ciudad { get; set; }

    public bool Estatus { get; set; }

    public DateTime Actualizado { get; set; }

    public virtual ICollection<ValeVehiculoCombustible> ValeVehiculoCombustibles { get; set; }
    public virtual ICollection<FacturaProveedor> FacturaProveedors { get; set; }
    public virtual ICollection<EntradaBascula> EntradaBasculas { get; set; }
}

** И его конфигурация

public class ProveedorConfiguration : EntityTypeConfiguration<Proveedor>
{
    public ProveedorConfiguration()
    {
        ToTable("Proveedor");

        //PK
        HasKey(p => p.Id_Proveedor);

        Property(p => p.Id_Proveedor)
            .IsRequired()
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(p => p.Codigo)
            .IsRequired()
            .HasColumnType("varchar")
            .HasMaxLength(6);
        HasIndex(p => p.Codigo)
            .IsUnique();

        Property(p => p.RazonSocial)
            .IsRequired()
            .HasColumnType("varchar")
            .HasMaxLength(60);

        Property(p => p.Calle)
            .IsRequired()
            .HasColumnType("varchar")
            .HasMaxLength(40);

        Property(p => p.Colonia)
            .HasColumnType("varchar")
            .HasMaxLength(30);

        Property(p => p.CCodigoPostalId)
            .IsRequired()
            .HasColumnType("int");

        Property(p => p.Telefonos)
            .HasColumnType("varchar")
            .HasMaxLength(30);

        Property(p => p.RFC)
            .HasColumnType("varchar")
            .HasMaxLength(13);
        HasIndex(p => p.RFC)
            .IsUnique();

        Property(p => p.CuentaContableId)
            .IsRequired();

        Property(p => p.DiasCred)
            .IsRequired()
            .HasColumnType("smallint");

        Property(p => p.SaldoMN)
            .IsRequired()
            .HasColumnType("decimal")
            .HasPrecision(10, 2);

        Property(p => p.AnticipoMN)
            .IsRequired()
            .HasColumnType("decimal")
            .HasPrecision(10, 2);

        Property(p => p.SaldoDlls)
            .IsRequired()
            .HasColumnType("decimal")
            .HasPrecision(8, 2);

        Property(p => p.AnticipoDlls)
            .IsRequired()
            .HasColumnType("decimal")
            .HasPrecision(8, 2);

        Property(p => p.Contacto)
            .HasColumnType("varchar")
            .HasMaxLength(60);

        Property(p => p.Email)
            .HasColumnType("varchar")
            .HasMaxLength(90);

        Property(p => p.Municipio)
            .HasColumnType("varchar")
            .HasMaxLength(50);

        Property(p => p.Estado)
            .HasColumnType("varchar")
            .HasMaxLength(31);

        Property(p => p.Ciudad)
            .HasColumnType("varchar")
            .HasMaxLength(45);

        Property(p => p.Estatus)
            .IsRequired();

        //Relationships
        //FK Proveedor -> ValeVehiculoCombustible
        HasMany(p => p.ValeVehiculoCombustibles)
            .WithOptional(v => v.Proveedor)
            .HasForeignKey(v => v.ProveedorId)
            .WillCascadeOnDelete(false);

        //PK Proveedor -> FacturaProveedor
        HasMany(p => p.FacturaProveedors)
            .WithRequired(f => f.Proveedor)
            .HasForeignKey(f => f.ProveedorId)
            .WillCascadeOnDelete(false);

        //FK Proveedor -> EntradaBasucla
        HasMany(p => p.EntradaBasculas)
            .WithRequired(e => e.Proveedor)
            .HasForeignKey(e => e.ProveedorId)
            .WillCascadeOnDelete(false);
    }
}

** И, наконец, вот результат запроса в режиме отладки ...

ViewSource Result

Это не то, что делает или должен делать TargetNullValue. Что вам нужно, так это MultiBinding с IMultiValueConverter, который возвращает первое ненулевое значение.

Dave M 20.10.2018 01:40

Спасибо, Дэйв М! Я понимаю использование мульти-привязок и целей, но пока не знаю, как поместить их в свой DataGrid с помощью CollectionViewSource. Какие-нибудь рекомендации? Заранее спасибо!

Rey Herrera 20.10.2018 18:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
1 696
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете привязаться к TargetNullValue. Вы можете указать только жестко запрограммированное значение. Если вы хотите связать, вы можете использовать DataGridTemplateColumn с Textblock и использовать DataTrigger на нем для изменения значения.

Итак, по умолчанию Textblock привязан к Municipio, затем, если это {x:Null}, привязать его к CCodigoPostal.Municipio.

<DataGrid.Columns>
    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBlock Text = "{Binding Path=Municipio}">
                     <TextBlock.Style>
                         <Style TargetType = "TextBlock">
                             <Setter Property = "Text" Value = "{Binding Path=Municipio}"></Setter>
                             <Style.Triggers>
                                 <DataTrigger Binding = "{Binding Path=Municipio}" Value = "{x:Null}">
                                     <Setter Property = "Text" Value = "{Binding Path=CCodigoPostal.Municipio}"></Setter>
                                  </DataTrigger>
                              </Style.Triggers>
                          </Style>
                      </TextBlock.Style>
                  </TextBlock>
              </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
  </DataGrid.Columns>

Если вы хотите сделать все возможное (и сделать это правильно), вы бы сделали DataTemplate в своих ресурсах и просто сослались бы на него, вместо того, чтобы помещать все xaml прямо в линию.

Если вы хотите использовать ресурс, вы должны поместить DataTemplate в свой Windows.Resources.

 <Window.Resources>
        <DataTemplate x:Key = "template">
            <TextBlock Text = "{Binding Path=Municipio}">
                <TextBlock.Style>
                    <Style TargetType = "TextBlock">
                        <Setter Property = "Text" Value = "{Binding Path=Municipio}"></Setter>
                        <Style.Triggers>
                            <DataTrigger Binding = "{Binding Path=Municipio}" Value = "{x:Null}">
                                <Setter Property = "Text" Value = "{Binding Path=CCodigoPostal.Municipio}"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </Window.Resources>

Затем установите CellTemplate.

 <DataGrid x:Name = "grid" Grid.Row = "3">
            <DataGrid.Columns>
                <DataGridTemplateColumn CellTemplate = "{StaticResource template}">
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

Привет, Джеймс !! Большое спасибо за ваш ответ, я понял смысл DataTemplate и триггеров ... но я не знаю, как я могу разместить их в качестве ресурса ... Кстати, использование {Binding Path = Municipio} не дает мне любое значение, обратите внимание, что я использую CollectionViewSource для заполнения DataGrid, поэтому ... я должен сначала сослаться на него, чтобы предоставить данные ?? ПД: Я очень ценю ваше время !.

Rey Herrera 20.10.2018 18:00

@ReyHerrera Я обновил свой ответ, указав, как использовать DataTemplate. Использование CollectionViewSource не имеет значения.

Brandon 22.10.2018 16:19

Джеймс, еще раз спасибо! Работает как шарм, но в какой-то момент мне кажется, что это не проверка значения x: Null. Я использовал <Style.Triggers> <DataTrigger Binding = "{Binding Path = Municipio}" Value = "{x: Null}"> <Setter Property = "Text" Value = "{Binding Path = CCodigoPostal.Municipio} "> </Setter> </DataTrigger> </Style.Triggers>

Rey Herrera 22.10.2018 22:26

<Style.Triggers> <DataTrigger Binding = "{Binding Path = Municipio}" Value = "{x: Статическая система: DBNull.Value}"> <Setter Property = "Text" Value = "{Binding Path = CCodigoPostal.Municipio} "> </Setter> </DataTrigger> </Style.Triggers>

Rey Herrera 22.10.2018 22:27

<Style.Triggers> <DataTrigger Binding = "{Binding Path = Municipio}" Value = "{x: Static system: String.Empty}"> <Setter Property = "Text" Value = "{Binding Path = CCodigoPostal.Municipio} "> </Setter> </DataTrigger> </Style.Triggers>

Rey Herrera 22.10.2018 22:27

но не меняет значение в конце, я думаю, что триггер не соответствует нулевому значению, возвращаемому с Sql Server.

Rey Herrera 22.10.2018 22:28

@ReyHerrera Какой тип у Municipio, и уверены ли вы, что это значение null? Если это string, вы можете столкнуться с тем, что на самом деле это не null. Вместо этого это будет пустая строка.

Brandon 22.10.2018 23:44

Что ж, я почти уверен, что моя таблица sql server возвращает null, но я не знаю, как мой DataGrid принимает значение, поэтому я пробовал эти триггеры ... кстати, Municipio - это varchar на sql server и string в C# (entity framework.

Rey Herrera 23.10.2018 00:54

@ReyHerrera Хорошо, я думаю, вместо того, чтобы проверять null, вам нужно проверять пустую строку. Так что замените {x:Null} на пустые кавычки и посмотрите, исправит ли это это.

Brandon 23.10.2018 17:42

ну уже пробовал, но все равно не работает ... а почему? мне нужно сделать преобразование?

Rey Herrera 23.10.2018 18:37

@ReyHerrera Можете ли вы проверить исходные данные, прежде чем настраивать сетку для проверки фактического значения? Часто, когда вы работаете с strings, они не будут нулевыми. Вместо этого они будут просто пустыми.

Brandon 23.10.2018 19:59

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

Rey Herrera 24.10.2018 00:09

@ReyHerrera Хорошо. Измените привязку обратно на ту, которую я указал в своем ответе, но добавьте к ней OneWay. Binding = "{Binding Path=Municipio, Mode=OneWay}". Пока вы используете INotifyPropertyChanged в своем классе, он должен работать.

Brandon 24.10.2018 00:13

@ReyHerrera Можете ли вы опубликовать класс элементов, к которым вы привязаны?

Brandon 24.10.2018 01:05

@ReyHerrera Посмотрите, здесь. Вам необходимо включить INotifyPropertyChanged в свой класс Proveedor, чтобы ваша привязка могла получать обновления. Это единственное, о чем я могу думать.

Brandon 24.10.2018 16:43

Другие вопросы по теме