如何获取使用星形定义的WPF网格列来剪辑内容?

我有一个使用星形比例的网格控件,例如

     

但是,在网格中放置一个长的TextBlock会导致比例被打乱。 例如

    

这导致中心列比另外两列多两倍。 如何保持指定的比例? 是否可以剪辑内容?

我在TextBlocks上设置了TextTrimming="CharacterEllipsis" ,但没有运气。

编辑

至关重要的是,Grid在DataTemplate ,粘贴以下内容来观察行为,

                  

这很重要的原因是我有另一个Grid作为ListBox的兄弟,它显示ListBox中显示的列的’headers’,如下所示,

  ... Headers and column definitions here      ... Matching column definitions here     

所以列匹配很重要。

我试图将DataTemplateColumnDefinitions绑定到外部Grid ColumnDefinitions但我无法轻易地获得对它的绑定引用。

这是WPF最烦人的问题之一。 由于产生于模板化网格的可用空间是无限的,因此实际内容将占用所需的空间。

最简单的方法是将一定宽度固定到网格,但这只解决了没有resize的情况。

虽然你想要拉伸ListBox大小(宽度,在特定的),不幸的是我想除了自定义转换器之外没有任何更好的解决方案。

这是我的解决方案:

                      

和转换器:

 class MyConv : IValueConverter { public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture ) { return (double)value - 30.0; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } 

虽然这是一篇旧post,但我正在添加我的发现,因为它们可能与阅读这篇文章的其他人有关。 我有一个类似的问题(我的*列没有按预期均匀划分宽度,它们只是根据内容resize)。 这里的根本原因是我有一个ListView,其中ItemsSource链接到List。 WPF中的ListView包含ScrollViewer,而ScrollViewer没有固定宽度。 如果没有固定宽度,网格无法正确确定要为*列提供的宽度,并切换到不同的大小调整方法。

解决方案我现在使用一个不包含ScrollViewer的ItemsControl,因此已知宽度允许Grid正确调整其列的大小。

有关Grid如何处理其大小调整的更多详细信息,我建议您反编译Grid类并查看以下方法:

 protected override Size MeasureOverride(Size constraint) 

这是我的测试应用程序中的MainWindow.xaml(注释掉ListView以查看行为的不同):

                                                  The ViewModels used during this test: using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; namespace WPFSO { public class SharedSizeScopeViewModel : INotifyPropertyChanged { public SharedSizeScopeViewModel() { var testEntries = new ObservableCollection(); testEntries.Add(new TestViewModel { Name = "Test", Name2 = "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong test", Name3 = "Short test", Name4 = "Nothing" }); Entries = testEntries; } private ObservableCollection _entries; public ObservableCollection Entries { get { return _entries; } set { _entries = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } 

第一个视图模型

 using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; namespace WPFSO { public class SharedSizeScopeViewModel : INotifyPropertyChanged { public SharedSizeScopeViewModel() { var testEntries = new ObservableCollection(); testEntries.Add(new TestViewModel { Name = "Test", Name2 = "Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong test", Name3 = "Short test", Name4 = "Nothing" }); Entries = testEntries; } private ObservableCollection _entries; public ObservableCollection Entries { get { return _entries; } set { _entries = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } 

第二个视图模型

 using System.ComponentModel; using System.Runtime.CompilerServices; namespace WPFSO { public class TestViewModel : INotifyPropertyChanged { private string _name; private string _name2; private string _name3; private string _name4; public string Name { get { return _name; } set { _name = value; OnPropertyChanged(); } } public string Name2 { get { return _name2; } set { _name2 = value; OnPropertyChanged(); } } public string Name3 { get { return _name3; } set { _name3 = value; OnPropertyChanged(); } } public string Name4 { get { return _name4; } set { _name4 = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } } 

 TextTrimming="CharacterEllipsis" 

在TextBlock上。

这个对我有用。 如您所定义,中间列的大小应该是另一列的两倍。