为什么不使用多值转换器设置数据网格中的列宽?

Why the width of column in the datagrid is not set with the multivalue converter?

我想用多值转换器设置列的宽度,但是没有设置宽度。

然后转换器,为了测试,总是return500。xaml代码是这样的:

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

我正在尝试设置单元格的宽度。也许我应该设置可视化树的另一个元素的宽度?

谢谢。

编辑:一个简单的例子

视图模型:

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

观点:

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

这个解决方案的问题是,使用幻灯片,我可以增加列的宽度,但不能减少。

另一个问题是如果在转换器中我return只是一个值,例如500,它没有被设置。

注意:我已经意识到,如果我将值加倍,它就会起作用。

但问题是我可以用幻灯片增加宽度,但不能减少。

转换器应该return一个DataGridLength来设置列的宽度:

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

这意味着您不能使用同一个转换器来设置列的 WidthTextBlock,因为后者需要 double.