C# 单击按钮时添加了一个空行
在我的GridView中,我有三种状态C# 单击按钮时添加了一个空行,c#,wpf,xaml,datatemplate,C#,Wpf,Xaml,Datatemplate,在我的GridView中,我有三种状态 仅查看 编辑 加 我想单击网格中的某个按钮以插入新行。 所以我有 public ObservableCollection<gridDataModel> GridCollection { get; set; } public void AddNewRow() { GridCollection.Insert(0, new gridDataModel()); } 公共ObservableCollection GridCollection
public ObservableCollection<gridDataModel> GridCollection { get; set; }
public void AddNewRow()
{
GridCollection.Insert(0, new gridDataModel());
}
公共ObservableCollection GridCollection{get;set;}
public void AddNewRow()
{
插入(0,新的gridDataModel());
}
我的问题是,我希望网格第一行中的列可以是文本框或下拉菜单。因此,当我插入新行时,我可以在文本框中填写数据,或者从下拉菜单中选择值
我所做的是自定义列的模板。比如说
<GridViewColumn Header="Databases" Width="498">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding DbName}">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding ViewStatus" Value="Visible">
<Setter Property="IsReadOnly" Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding ViewStatus" Value="Visible">
<Setter Property="IsReadOnly" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding AddStatus" Value="Visible">
<Setter Property="IsReadOnly" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
在视图状态下,每个单元格都是只读的
在编辑状态下,某些列是只读的。其他的可以编辑
最难的部分是添加状态。我只希望第一行(新添加的行)处于编辑状态。这意味着第一行可以编辑,其余的是只读的
如何使用?您可以在多种条件下使用
MultiDataTrigger
。使用多数据触发器
时,必须满足所有条件才能应用setter(逻辑和)
在您的情况下,您需要两个条件-行索引=0和AddStatus=Visible但是,当您添加另一行时,您需要以某种方式禁用旧行的触发器 3) 多值转换器
public class MyMultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var listViewItem = (ListViewItem)values[0];
ListView listView = (ListView)ItemsControl.ItemsControlFromItemContainer(listViewItem);
int index = listView.ItemContainerGenerator.IndexFromContainer(listViewItem);
if (values[1] == DependencyProperty.UnsetValue)
{
/*i.e. Object1.Object2.AddStatus - if Object2 is null then binding will return UnsetValue */
return false;
}
Visibility addStatus = (Visibility)values[1];
return index == 0 && addStatus == Visibility.Visible;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
添加新行
项目时,列表视图的Count
将重新触发多值转换器
,这是最难的部分,即禁用旧行的触发。我更新了答案。不太理想,但应该能解决你的问题谢谢你的帮助。实际上,我想在model类中创建一个名为rowNumber
的属性。因此,当我创建新行时,我可以将其设置为0
或特殊值,如-1
。对于其他行,属性为正整数。如果是,那怎么办?
public class GetRowIndexConverter : IValueConverter
{
/// <inheritdoc />
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = (ListViewItem)value;
var listView = (ListView)ItemsControl.ItemsControlFromItemContainer(item);
int index = listView.ItemContainerGenerator.IndexFromContainer(item);
return index;
}
/// <inheritdoc />
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource MyMultiValueConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}" />
<Binding Path="AddStatus" />
<!--Count is observable, so every time when collection gets modified system will re-trigger our multi-converter-->
<Binding Path="Items.Count" ElementName="MyListView" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="IsReadOnly" Value="True" />
</DataTrigger>
public class MyMultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var listViewItem = (ListViewItem)values[0];
ListView listView = (ListView)ItemsControl.ItemsControlFromItemContainer(listViewItem);
int index = listView.ItemContainerGenerator.IndexFromContainer(listViewItem);
if (values[1] == DependencyProperty.UnsetValue)
{
/*i.e. Object1.Object2.AddStatus - if Object2 is null then binding will return UnsetValue */
return false;
}
Visibility addStatus = (Visibility)values[1];
return index == 0 && addStatus == Visibility.Visible;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}