C# DataGridTemplateColumn中的组合框未调整大小 问题导论
我有一个C# DataGridTemplateColumn中的组合框未调整大小 问题导论,c#,wpf,combobox,datagrid,C#,Wpf,Combobox,Datagrid,我有一个DataGrid,它有一个DataGridTemplateColumn,其模板包含一个组合框控件。我的问题是,当所选项目的显示成员太长,无法容纳组合框的宽度时,组合框的宽度不会扩展以适应显示的成员的宽度,就像在数据网格中没有相同的组合框时一样 工作示例 main window.xaml MainWindow.xaml.cs 使用系统; 使用System.Collections.Generic; 使用System.Collections.ObjectModel; 使用系统组件模型; 使
DataGrid
,它有一个DataGridTemplateColumn
,其模板包含一个组合框
控件。我的问题是,当所选项目的显示成员太长,无法容纳组合框的宽度时,组合框的宽度不会扩展以适应显示的成员的宽度,就像在数据网格中没有相同的组合框时一样
工作示例
main window.xaml
MainWindow.xaml.cs
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
使用System.Windows.Input;
命名空间WpfApplication1
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口,INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
公共静态字典可用性操作{get;set;}
公共EntityClass SelectedEntity{get;set;}
公共ObservableCollection实体{get;set;}
公共AddRowCommandClass AddRowCommand{get;set;}
公共RemoveRowCommandClass RemoveRowCommand{get;set;}
静态主窗口()
{
AvailableActions=新字典()
{
{ActionType.Accept,“接受文本”},
{ActionType.Reject,“拒绝文本”},
{ActionType.Refere,“引用文本”},
{ActionType.delayer,“推迟文本”},
};
}
公共主窗口()
{
实体=新的ObservableCollection()
{
新EntityClass(){Text=“第一个示例文本”,Action=ActionType.Accept},
新EntityClass(){Text=“第二个示例文本”,Action=ActionType.Reject},
新EntityClass(){Text=“第三个示例文本”,Action=ActionType.refere},
};
AddRowCommand=新的AddRowCommandClass(此);
RemoveRowCommand=新的RemoveRowCommandClass(此);
初始化组件();
}
公共枚举操作类型
{
接受
拒绝
参考
推迟
}
公共类实体类
{
公共字符串文本{get;set;}
公共ActionType操作{get;set;}
}
公共类AddRowCommandClass:ICommand
{
公共事件处理程序CanExecuteChanged;
专用主窗口(u)窗口;;
公共AddRowCommandClass(主窗口)
{
_窗口=窗口;
}
公共布尔CanExecute(对象参数)
{
返回true;
}
public void Execute(对象参数)
{
_添加(新EntityClass(){Text=“Hello World!”,Action=ActionType.delay});
}
}
公共类RemoveRowCommandClass:ICommand
{
公共事件处理程序CanExecuteChanged;
专用主窗口(u)窗口;;
公共RemoveRowCommandClass(主窗口)
{
_窗口=窗口;
}
公共布尔CanExecute(对象参数)
{
返回_window.SelectedEntity!=null;
}
public void Execute(对象参数)
{
_window.Entities.Remove(_window.SelectedEntity);
_window.SelectedEntity=null;
_window.PropertyChanged?.Invoke(_window,newpropertyChangedEventArgs(“SelectedEntity”);
}
}
}
}
复制步骤
- 首先观察页面底部的
组合框
会随着所选值的大小变化而变化
- 接下来,在
数据网格中添加一个新行
,或编辑已有行中的组合框
,以选择“推迟文本”
选项;请注意,组合框
不会改变大小以适应较大的文本,从而导致文本被剪裁
- 最后,使用其中一行选择了“推迟文本”
,将窗口调整为更大的大小,并注意到组合框现在是如何增加宽度以适应较长的文本而不进行剪切的
结论/问题
我的问题是如何强制组合框
控件自动调整其所选项目的宽度,并在必要时增加网格行的宽度。我希望所选文本永远不会被剪裁,即使这意味着修改数据网格中特定列的宽度以适应。我建议将第二列的宽度从“自动”设置为“*”,就像您在第一列中所做的那样。然后设置MaxWidth,这样组合框在调整大小时不会变大
<DataGridTemplateColumn Width="*" MaxWidth="200"
CanUserReorder="False" CanUserResize="False"
CellTemplate="{StaticResource ComboBox_Template}"
Header="Action"/>
我建议将第二列的宽度从“自动”设置为“*”,就像您在第一列中所做的那样。然后设置MaxWidth,这样组合框在调整大小时不会变大
<DataGridTemplateColumn Width="*" MaxWidth="200"
CanUserReorder="False" CanUserResize="False"
CellTemplate="{StaticResource ComboBox_Template}"
Header="Action"/>
使用简单得多的数据网格,问题是可以重现的:只需将一个星形大小的列放在另一个非星形大小的列之前。布局过程不会尝试将列向左收缩,以便在网格大小保持不变的情况下为右侧的列提供更多空间
以下解决方案基于
建立一些事件,指出可能需要调整列大小,然后删除星形列宽,更新布局,恢复列宽。在我的示例中,我使用了SelectionChanged
事件a
<Grid x:Name="grid1">
<Grid.Resources>
<CollectionViewSource x:Key="ComboBoxItemsSource" Source="{Binding ComboItems}"/>
</Grid.Resources>
<DataGrid
x:Name="dg1"
ItemsSource="{Binding DataItems}"
AutoGenerateColumns="False"
SelectionChanged="dg1_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn
Width="*"/>
<DataGridComboBoxColumn
Header="B"
ItemsSource="{Binding Source={StaticResource ComboBoxItemsSource}}"
SelectedItemBinding="{Binding Text}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
public MainWindow()
{
InitializeComponent();
grid1.DataContext = vm = new MyViewModel()
{
DataItems =
{
new ItemVM(),
},
ComboItems =
{
"A",
"AAAAAAAAAAAAAAAAAAAAAAA"
}
};
}
public class MyViewModel
{
private ObservableCollection<ItemVM> _DataItems = new ObservableCollection<ItemVM>();
public ObservableCollection<ItemVM> DataItems
{
get { return _DataItems; }
}
private ObservableCollection<string> _ComboItems = new ObservableCollection<string>();
public ObservableCollection<string> ComboItems
{
get { return _ComboItems; }
}
}
public class ItemVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent([CallerMemberName]string prop = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(prop));
}
private string _Text;
public string Text
{
get { return _Text; }
set { _Text = value; RaisePropertyChangedEvent(); }
}
}
<DataGridTemplateColumn Width="Auto"
CanUserReorder="False" CanUserResize="False"
Header="Action">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Margin="2 2 2 2"
ItemsSource="{Binding Path=DataContext.AvailableActions,
Mode=OneTime,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
SelectedValue="{Binding Path=Action, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Key"
DisplayMemberPath="Value"
IsEditable="False"
IsSynchronizedWithCurrentItem="False"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>