【问题标题】:How to get object of list after object's property has been updated in ListView在ListView中更新对象属性后如何获取列表对象
【发布时间】:2019-01-24 08:54:15
【问题描述】:

我正在制作一个充满对象列表的 ListView,这些属性在 ListView 中显示和编辑。我需要在更新其属性时获取对象。我该怎么做?

我尝试创建一个类对象并将其绑定到 ListView 中的 SelectedItem。问题是,显然,SelectedItem 是在单击 ListItem 的行之后设置的,而不是该行的子项。每次更改任何 ComboBox 或 TextBox 值后,我都需要从 ListView 的行中获取更新的对象。

要使用 INotifyPropertyChanged 处理所有事情,我使用的是 PropertyChanged.Fody。它可以帮助我更轻松地解决这个问题吗?

查看

Appearance of the ListView

<ListView 
        Margin="10"
        Grid.Row="1"
        Grid.ColumnSpan="2"
        ItemsSource="{Binding TimesheetEntries}"
        SelectedItem="{Binding SelectedEntry, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        >
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Height="30" Margin="3">
                    <TextBlock 
                        Text="{Binding Date, StringFormat=dd-MM-yyyy}" 
                        VerticalAlignment="Center" 
                        Width="Auto" 
                        Margin="10"/>
                    <ComboBox 
                        SelectedValuePath="Key" DisplayMemberPath="Value" 
                        ItemsSource="{Binding EmploymentTypesDictionary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                        SelectedValue="{Binding SelectedEmployment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        Width="270"/>
                    <TextBox 
                        Text="{Binding Hours, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                        Margin="10,0,0,0"
                        Width="70"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

视图模型

public List<TimesheetEntryEntity> TimesheetEntries
{
    get { return _TimesheetEntries; }
    set { _TimesheetEntries = value; }
}

public TimesheetEntryEntity SelectedEntry
{
    get { return _SelectedEntry; }
    set { _SelectedEntry = value; }
}

...

private List<TimesheetEntryEntity> _TimesheetEntries { get; set; }
private TimesheetEntryEntity _SelectedEntry;
private TimesheetModel timesheetModel;
public TimesheetViewModel()
{
        this.Timesheets = TimesheetUnitModel.GetAllTimesheetsForUnit((int)Application.Current.Properties["UnitID"]);
        this._StartDate = DateTime.Now;
        _TimesheetEntries = new List<TimesheetEntryEntity>();
}
public KeyValuePair<int, string> SelectedWorker
{
    get { return _SelectedWorker; }
    set
    {
        _SelectedWorker = value;
        _TimesheetEntries =
                timesheetModel.GetTimesheetList(_SelectedWorker.Key, SelectedTimesheet.Key, StartDate.Date);
    }
}

TimesheetEntryEntity

    public DateTime Date { get; set; }

    public Dictionary<EmploymentTypes, string> EmploymentTypesDictionary { get; set; }

    public EmploymentTypes SelectedEmployment {
        get { return _SelectedEmployment; }
        set
        {
            _SelectedEmployment = value;
            CheckHoursAvaliability();
        }
    }
    public bool HoursAvaliable { get; set; }

    public decimal Hours
    {
        get;
        set;
    }
    private EmploymentTypes _SelectedEmployment;

    public TimesheetEntryEntity()
    {
        FillEmploymentTypes();
    }

    public void FillEmploymentTypes()
    {
        //Some code here
    }

我尝试遵循Get Object properties of selected list item 问题的答案,但只有文本块,因此无论如何都会选择该行,但我有 ComboBox 和 TextBox,它们有自己的焦点。

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    您可以在 TimesheetEntryEntity 中实现 INotifyPropertyChanged,即

    public abstract class TimesheetEntryEntity: INotifyPropertyChanged
    {
        public event EventHandler Changed;
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public void OnChange()
        {
            EventHandler handler = Changed;
            handler?.Invoke(this, EventArgs.Empty);
        }
        private DateTime date;
        public DateTime Date
        {
            get => date;
            set
            {
                if (date == value)
                {
                    return;
                }
                //Do something with unchanged property
                date = value;
                RaisePropertyChanged();
                OnChange();
                //Do something with changed property
            }
        }
    

    在将新项目添加到列表之前在您的 ViewModel 中:

       timesheet.Changed+=ItemChanged;
    

     private void ItemChanged(object sender, EventArgs e)
        {
           var item=sender as TimesheetEntryEntity;
           //do something    
        }
    

    【讨论】:

    • 我从我的模型中获取了预填充的列表,因此在使用foreach 在 ViewModel 中获取列表后,我必须为每个对象分配事件。但它完美无缺,谢谢。
    猜你喜欢
    • 2021-02-06
    • 1970-01-01
    • 2014-02-04
    • 2010-09-27
    • 2017-06-29
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多