Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单击按钮时添加了一个空行_C#_Wpf_Xaml_Datatemplate - Fatal编程技术网

C# 单击按钮时添加了一个空行

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

在我的GridView中,我有三种状态

  • 仅查看

  • 编辑

  • 我想单击网格中的某个按钮以插入新行。 所以我有

    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(逻辑

    在您的情况下,您需要两个条件-行索引=0AddStatus=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();
        }
    }