2

我有一个ListBox绑定到ObservableCollection<Series>视图模型中的一个。每次用户单击“删除”按钮时,Delete DelegateCommand都会在类内执行特定项目Series,并将项目从数据库中删除。

我正在寻找某种方法来更新ObservableCollection<Series>发生这种情况的时间,以便在删除相关项目后立即将其从 XAML 视图中删除。

目前这没有发生,我对 WPF 比较陌生,并且一直试图让它工作好几天,请提出我哪里出错了:

相关 XAML:

<ListBox ItemsSource="{Binding SeriesCollection}" Name="lbSeries" Background="#6E7587" ItemContainerStyle="{StaticResource highlightStyle}" SelectionMode="Single" AlternationCount="2" Grid.Row="2" ScrollViewer.VerticalScrollBarVisibility="Auto">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="200" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBox Margin="5,0" FontSize="14" Name="txtName" Text="{Binding Name}" Width="190" Height="30" Grid.Column="0" />
                <wpfToolkit:IntegerUpDown Value="{Binding Season}"  Name="nudSeason" FontSize="14" Height="30" Width="95" Increment="1" Maximum="100000" Minimum="0" Grid.Column="1" />
                <wpfToolkit:IntegerUpDown Value="{Binding Episode}" Name="nudEpisode" FontSize="14" Height="30" Width="95" Increment="1" Maximum="100000" Minimum="0" Grid.Column="2" />
                <Button Command="{Binding Save}" Grid.Column="3" Width="60" Height="50" Cursor="Hand" ToolTip="Save program" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Button.Template>
                        <ControlTemplate>
                            <Border HorizontalAlignment="Center" VerticalAlignment="Center" >
                                <Image Source="Resources\Save.png" Width="30" Height="40" />
                            </Border>
                        </ControlTemplate>
                    </Button.Template>
                </Button>
                <Button Command="{Binding Delete}" Grid.Column="4" Width="60" Height="50" Cursor="Hand" CommandParameter="{Binding ElementName=lbSeries,Path=SelectedItem}" ToolTip="Remove program" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="15,0">
                    <Button.Template>
                        <ControlTemplate>
                            <Border HorizontalAlignment="Center" VerticalAlignment="Center" >
                                <Image Source="Resources\Delete.png" Width="30" Height="40" />
                            </Border>
                        </ControlTemplate>
                    </Button.Template>
                </Button>
                <Label Content="{Binding Information}" Grid.Column="5" FontSize="14" Margin="10,0" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

查看型号:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using SeriesTracker.Functions;
using System.Linq;

namespace SeriesTracker.Client
{
    public class SeriesTrackerViewModel : INotifyPropertyChanged
    {
        public DelegateCommand NewSeries { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private ObservableCollection<Series> _series = new ObservableCollection<Series>();
        public ObservableCollection<Series> SeriesCollection
        {
            get { return _series; }
            set
            {
                _series = value;
                RaisePropertyChanged("SeriesCollection");
            }
        }

        public SeriesTrackerViewModel()
        {
            NewSeries = new DelegateCommand(AddNewSeries);

            DataTable table = DataAccessLayer.GetSeries();
            if (table.Rows.Count > 0)
                LoadSeries(table);
        }

        private void LoadSeries(DataTable table)
        {
            foreach (DataRow row in table.Rows)
            {
                int id = Int32.Parse(row["Id"].ToString());
                string name = row["Name"].ToString();

                int season = 0;
                int episode = 0;

                if (Int32.TryParse(row["Season"].ToString(), out season) &&
                    Int32.TryParse(row["Episode"].ToString(), out episode))
                {
                    var series = new Series(id, name, season, episode);
                    SeriesCollection.Add(series);
                }
            }
        }

        public void AddNewSeries()
        {
            SeriesCollection.AddSeries();
        }

        private void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

系列类:

using System;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace SeriesTracker.Functions
{
    public class Series : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private DelegateCommand _save;
        public DelegateCommand Save 
        {
            get { return _save; }
            set
            {
                _save = value;
                RaisePropertyChanged("Save");
            }
        }

        private DelegateCommand _delete;
        public DelegateCommand Delete 
        { 
            get{return _delete;}
            set
            {
                _delete = value;
                RaisePropertyChanged("Delete");
            }
        }

        public int Id { get; set; }

        string _name;
        public String Name
        {
            get { return _name; } 
            set
            {
                _name = value;
                RaisePropertyChanged("Name");
            }
        }

        int _season;
        public Int32 Season 
        {
            get { return _season; } 
            set
            {
                _season = value;
                RaisePropertyChanged("Season");
            }
        }

        int _episode;
        public Int32 Episode 
        {
            get { return _episode; }
            set
            {
                _episode = value;
                RaisePropertyChanged("Episode");
            }
        }

        string _information;
        public String Information 
        {
            get { return _information; }
            set
            {
                _information = value;
                RaisePropertyChanged("Information");
            }
        }

        public Series(int id,string name,int season, int episode)
        {
            Id = id;
            Name = name;
            Season = season;
            Episode = episode;

            Save = new DelegateCommand(SaveItem);
            Delete = new DelegateCommand(DeleteItem);
        }

        public void DeleteItem()
        {
            var selectedItem = this;
            if (selectedItem.Id != -1)
            {
                DataAccessLayer.Delete(selectedItem.Id);
            }
        }

        public void SaveItem()
        {
            var selectedItem = this;
            if (selectedItem.Id == -1)
                DataAccessLayer.AddEntry(selectedItem.Name,selectedItem.Season,selectedItem.Episode);
            else
                DataAccessLayer.Update(selectedItem.Id,
                    selectedItem.Name,selectedItem.Season,selectedItem.Episode);
        }

        private void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
4

2 回答 2

4

您不应该将 DeleteCommand 保留在 Series 类中,它应该在视图模型上。

在视图模型中,您可以轻松更新 ObservableCollection。

您需要在 ViewModel 和 XAML 上使用类型系列的通用委托命令,您需要在命令参数上传递 {Binding}。

查看模型 C#:-

DelegateCommand<Series> DeleteCommand { get; set; } 
DeleteCommand = new RelayCommand<Series>(OnDelete); 

// This method will gets execute on click the of Delete Button1
private void OnDelete(Series series) 
{
}

XAML :- 在删除按钮上更改绑定和命令参数值

CommandParameter="{Binding }"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"

希望对你有帮助

于 2012-08-13T06:08:50.063 回答
1

您可以订阅 中PropertyChangedEventHandler的每个系列ObservableCollection,然后RaisePropertyChanged("SeriesCollection")在事件触发时调用

更新:我的意思是这样的:

private void LoadSeries(DataTable table)
{
    ...
    {
        var series = new Series(id, name, season, episode);
        series.PropertyChanged += { RaisePropertyChanged("SeriesCollection"); }
        SeriesCollection.Add(series);
    }
}       
于 2012-08-13T06:25:59.110 回答