Home > front end >  Why the width of column in the datagrid is not set with the multivalue converter?
Why the width of column in the datagrid is not set with the multivalue converter?

Time:04-08

I want to set the width of a column with a multivalue converter, but the width is not set.

Then converter, for testing, always return 500. The xaml code is this:

                    <DataGridTextColumn Header="Modelo"
                                        Binding="{Binding Modelo}"
                                        HeaderStyle="{StaticResource DataGridColumnHeaderLeftAlignement}">
                        <DataGridTextColumn.CellStyle>
                            <Style TargetType="DataGridCell" BasedOn="{StaticResource ResourceKey=DataGridCellLeftHorizontalAlignment}">
                                <Setter Property="Width">
                                    <Setter.Value>
                                        <MultiBinding Converter="{StaticResource docListadosDocumentosDataGridComponentesColumnWidthMultiValueConverter}">
                                            <MultiBinding.Bindings>
                                                <Binding />
                                            </MultiBinding.Bindings>
                                        </MultiBinding>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGridTextColumn.CellStyle>
                    </DataGridTextColumn>

I am trying to set the width of the cell. Perhaps should I set up the width of of another element of the visual tree?

Thanks.

EDIT: a simple example

The view model:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using System.Runtime.CompilerServices;
using System.Globalization;

namespace ModificarColumnaDataGridConMultivalueConverter
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ViewModel()
        {
            ObservableCollection<Data> col = new ObservableCollection<Data>();
            col.Add(new Data() { SomeString = 44 });
            col.Add(new Data() { SomeString = 84 });
            col.Add(new Data() { SomeString = 104 });
            cvs.Source = col;
        }
        private CollectionViewSource cvs = new CollectionViewSource();
        public ICollectionView View { get => cvs.View; }

        private double _widthValue = 30;
        public double WidthValue
        {
            get => this._widthValue;
            set { this._widthValue = value; OnPorpertyChanged(); }
        }

        private bool _widthDefault = false;
        public bool WidthDefault
        {
            get => this._widthDefault;
            set { this._widthDefault = value; OnPorpertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        internal void OnPorpertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }


    public class Data
    {
        public double SomeString { get; set; }
    }

    public class MyMultiValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return (double)200;
            double w = 30;
            if (!(bool)values[1]) double.TryParse(values[0].ToString(), out w);
            return w;
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

The view:

<Window x:Class="ModificarColumnaDataGridConMultivalueConverter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ModificarColumnaDataGridConMultivalueConverter"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">


    <Window.Resources>
        <local:ViewModel x:Key="vm"/>
        <local:MyMultiValueConverter x:Key="MyMultiValueConverter"/>
    </Window.Resources>
    <StackPanel DataContext="{StaticResource vm}">
        <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Col1"  Binding="{Binding SomeString}"  MinWidth="0" MaxWidth="300"  >
                    <DataGridTextColumn.Width>
                        <MultiBinding Converter="{StaticResource MyMultiValueConverter}">
                            <Binding Path="WidthValue" Source="{StaticResource vm}"/>
                            <Binding Path="WidthDefault" Source="{StaticResource vm}"/>
                        </MultiBinding>
                    </DataGridTextColumn.Width>
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="TextAlignment" Value="Center"/>
                            <Setter Property="Width">
                                <Setter.Value>
                                    <MultiBinding Converter="{StaticResource MyMultiValueConverter}">
                                        <Binding Path="WidthValue" Source="{StaticResource vm}"/>
                                        <Binding Path="WidthDefault" Source="{StaticResource vm}"/>
                                    </MultiBinding>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
        <CheckBox IsChecked="{Binding WidthDefault}" Content="Default Width"/>
        <Slider Width="200" Height="20" Minimum="5"  Maximum="300" Value="{Binding WidthValue}"/>
        <!--<TextBox Text="{Binding WidthValue}"/>-->
    </StackPanel>
</Window>

The problem with this solution is that with the slide, I can encrease the width of the column, but I can't decrease.

Another problem is if in the converter I return just a value, for example 500, it is not setted.

NOTE: I have realised that if I cast to double the value it works.

But the problem is that I can increase the width with the slide, but not decrease.

CodePudding user response:

The converter should return a DataGridLength for the width of the column to be set:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    double w = 30;
    if (!(bool)values[1]) double.TryParse(values[0].ToString(), out w);
    return new DataGridLength(w);
}

This means that you cannot use the same converter to set the Width of the column and the TextBlock since the latter expects a double.

  • Related