Rey Herrera
Rey Herrera

Reputation: 43

How do i set a Binding Value to a TargetNullValue property in a DataGridTextColumn WPF XAML

i'm trying to put a default value on my DataGridTextColumn in case the Binding Property gives Null Value, like and if in sql server...

So i researched and found the property TargetNullValue where can i put a default value in case the column have a null.

But is not working as i am doing it. Throws me the next error

System.Windows.Markup.XamlParseException: 'A 'Binding' cannot be set on the 'TargetNullValue' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'

Here is a example of my XAML code.

<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>

with the current resources

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

Actually is binded with EntityFramework using DataSource...

Thank you so much in advance!

*Updated CLASS

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; }
}

** And his configuration

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);
    }
}

** And finally, here is the returned result of the query at debug mode...

ViewSource Result

Upvotes: 4

Views: 4280

Answers (1)

Brandon
Brandon

Reputation: 3266

You can't bind to TargetNullValue. You can only put a hard-coded value in there. If you want to bind, you can use a DataGridTemplateColumn with a Textblock and use a DataTrigger on it to change the value.

So, default the Textblock to bind to Municipio, then if it's {x:Null}, then bind it to 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>

If you want to go above and beyond (and do it right), you'd make a DataTemplate in your resources and just reference that instead of putting all the xaml right in-line.

If you want to use a resource, you would put the DataTemplate in your 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>

Then, set the CellTemplate.

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

Upvotes: 3

Related Questions