为什么不使用多值转换器设置数据网格中的列宽?
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);
}
这意味着您不能使用同一个转换器来设置列的 Width
和 TextBlock
,因为后者需要 double
.
我想用多值转换器设置列的宽度,但是没有设置宽度。
然后转换器,为了测试,总是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);
}
这意味着您不能使用同一个转换器来设置列的 Width
和 TextBlock
,因为后者需要 double
.