如何在更新wpf中的现有项目的同时向itemscontrol添加新项目

时间:2015-03-19 12:32:18

标签: c# wpf

解释我的问题非常困难,但我会尝试一下。

我有一个带有按钮的ItemTemplate的ItemsControl,点击按钮我必须将新的Item添加到ItemsControl。最后一行应该只有按钮。

问题 我最初能够在绑定期间隐藏行的按钮(除了最后一行),但是在单击按钮并添加动态行时我无法隐藏上一个按钮。

希望我已经解释了我的问题。如果不够清楚,请告诉我。我无法解决这个问题。

这是我的实施

我的主窗口

<Window x:Class="ObservableCollectionUpdation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ObservableCollectionUpdation"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <local:IsLastItemConverter x:Key="LastItemConverter"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="60"/>
        </Grid.RowDefinitions>

        <ItemsControl x:Name="RecordsControl" ItemsSource="{Binding Records}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="150"/>
                            <ColumnDefinition Width="150"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding Name}"></TextBlock>
                        <TextBlock Grid.Column="1" Text="{Binding TotalCount}"></TextBlock>
                        <Button Grid.Column="2" Content="Add" Command="{Binding ElementName=RecordsControl, Path= DataContext.AddCommand}"
                                Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                                Converter={StaticResource LastItemConverter}}"></Button>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

MyViewModel,记录和命令类

public class MyViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Record> Records { get; set; }
    public DelegateCommand AddCommand { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public MyViewModel()
    {
        AddCommand = new DelegateCommand(DoAdd);
        Records = new ObservableCollection<Record>
        {
            new Record {Name = "One", TotalCount =1},
            new Record{Name="Second", TotalCount=1}
        };
    }

    private void DoAdd()
    {
        Records.Add( new Record
        {
            Name = "Added",
            TotalCount = Records.Count + 1
        });
        OnPropertyChanged("Records");
    }
}


public class Record
{
    public string Name { get; set; }
    public int TotalCount { get; set; }
}

public class DelegateCommand : ICommand
{
    private readonly Action _executeMethod;

    public DelegateCommand(Action executeMethod)
    {
        _executeMethod = executeMethod;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _executeMethod.Invoke();
    }
}

转换器

public class IsLastItemConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
                              object parameter, CultureInfo culture)
        {
            DependencyObject item = (DependencyObject)value;
            ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);

            return (ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1) ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType,
                                  object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

2 个答案:

答案 0 :(得分:0)

问题是为每一行单独调用转换器,并且在评估该行时,这是最后一行,因此所有行都可见

可以通过多种方式处理此问题,最简单的方法是将新项目作为属性,并且仅在newItem更改更新可见性时

答案 1 :(得分:0)

我不知道这个有效的解决方案,但这是我发现的解决方案。这是将集合重新绑定到控件,因此更改DoAdd方法以重新创建ObservableCollection解决了问题

        private void DoAdd()
        {
            Records.Add( new Record
            {
                Name = "Added",
                TotalCount = Records.Count + 1
            });

            Records = new ObservableCollection<Record>(Records);
            OnPropertyChanged("Records");
        }