如何将ListBox SelectedItem放入ViewModel类的实例中

本文关键字:实例 ViewModel 放入 ListBox SelectedItem | 更新日期: 2023-09-27 18:14:20

我的列表框的SelectedItem有一个问题。我想把选中的项放在HealthDiseaseViewModel的highlight属性中这是我的ViewModel:

public class HealthDiseaseViewModel : ObservableCollection<HealthDisease>
{
    private string _feedBack;
    HealthDiseaseDb _db = new HealthDiseaseDb();
    public HealthDiseaseRetrieveSingleCommand RetrieveSingleCommand { get; set; }
    public HealthDiseaseRetrieveManyCommand RetrieveManyCommand { get; set; }   
    public HealthDiseaseUpdateCommand UpdateCommand { get; set; }   
    public HealthDisease Entity { get; set; }
    public HealthDisease Highlighted { get; set; }
    public List<HealthDisease> EntityList { get; set; }
    public HealthDiseaseViewModel()
    {
        RetrieveSingleCommand = new HealthDiseaseRetrieveSingleCommand(this);
        RetrieveManyCommand = new HealthDiseaseRetrieveManyCommand(this);       
        UpdateCommand = new HealthDiseaseUpdateCommand(this);       
        Highlighted = new HealthDisease();
        Entity = new HealthDisease();
        RetrieveMany(Entity);
    }
    #region Methods
    public void Retrieve(HealthDisease parameters)
    {
        Highlighted = _db.Retrieve(parameters);            
    }
    public void RetrieveMany(HealthDisease parameters)
    {
        EntityList = new List<HealthDisease>();
        EntityList = _db.RetrieveMany(parameters);      
        IList<HealthDisease> toBeRemoved = Items.ToList();
        foreach (var item in toBeRemoved)
        {
            Remove(item);
        }
        foreach (var item in EntityList)
        {
            Add(item);
        }           
    }
    public void Insert(HealthDisease entity)
    {
        bool doesExist = false;
        if (_db.Insert(entity, SessionHelper.CurrentUser.Id, ref doesExist))
        {
            _feedBack = "Item Successfully Saved!";
            RetrieveMany(new HealthDisease());
        }
        else if (doesExist)
        {
            _feedBack = "Item Already Exists!";
        }
        else
        {
            _feedBack = "Not All Fields Were Filled-In!";
        }
        MessageBox.Show(_feedBack, "Item Insertion");
    }
    public void Update(HealthDisease entity)
    {
        bool doesExist = false;
        if (_db.Update(entity, SessionHelper.CurrentUser.Id, ref doesExist))
        {
            _feedBack = "Item Successfully Updated!";
            RetrieveMany(new HealthDisease());
        }
        else if (doesExist)
        {
            _feedBack = "Item Already Exists!";
        }
        else
        {
            _feedBack = "Not All Fields Were Filled-In!";
        }
        MessageBox.Show(_feedBack, "Item Edition");
    }
    public void Delete(HealthDisease entity)
    {
        var answer = MessageBox.Show(String.Format("Are you sure you want to delete 'n{0}?", entity.Name), 
        "Item Deletion", MessageBoxButtons.YesNo);
        if (answer == DialogResult.No)
        {
            return;
        }
        if (_db.Delete(entity, SessionHelper.CurrentUser.Id))
        {
            _feedBack = "Item Successfully Deleted!";
            RetrieveMany(new HealthDisease());
        }
        MessageBox.Show(_feedBack, "Item Deletion");
    }   
    #endregion   
}

我将我的ListBox的SelectedItem绑定为高亮,我希望它高亮。名称和高亮显示。Description到TextBlocks,但是TextBlocks不显示SelectedItem。我可以通过使用SelectedItem在这里做一个工作。名称和SelectedItem。描述,但问题是它会自动更新列表框,即使我没有点击保存按钮。使用对象高亮将解决这个问题,但我已经花了几个小时的挫折。这是我的加价。我省略了从ViewModel中绑定到UpdateCommand的SaveButton

<Grid Name="MainGrid" Background="Aqua" MinWidth="500" MinHeight="400" 
      DataContext="{Binding Source={StaticResource HealthViewModel}}">
    <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding Path=Highlighted.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
        <ListBox x:Name="EntityListBox" Margin="10,0" Height="380"
            ItemsSource="{Binding }"
            DisplayMemberPath="Name"
            SelectedItem="{Binding Path=Highlighted, Mode=TwoWay, 
                                   Converter={StaticResource ToHealthDiseaseConverter}, 
                                   UpdateSourceTrigger=PropertyChanged}" />
    </StackPanel>   
</Grid>

如何将ListBox SelectedItem放入ViewModel类的实例中

我可以给你一个快速的答案,但有点希望你不要停在这里,试图找出为什么绑定到一个对象的属性不会工作。DependencyProperty绑定到实现INotifyPropertyChanged的实例,并正确引发PropertyChanged触发器。它不绑定到实例的"值"。看看你是否能弄清楚为什么绑定到高亮显示。名字不起作用。

我为你创建了一个简化的示例

<Window x:Class="WpfTestProj.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:WpfTestProj"
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=False}"
    Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
<Grid>
    <StackPanel Orientation="Vertical">
        <StackPanel>
            <TextBlock Text="{Binding Path=HighlightedName}" />
        </StackPanel>
        <StackPanel>
            <ListBox x:Name="EntityListBox" Margin="10,0"
                ItemsSource="{Binding EntityList}"
                DisplayMemberPath="Name"
                SelectedItem="{Binding Path=Highlighted, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
     </StackPanel>
</Grid>

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class HealthDisease
{
    public string Name { get; set; }
}
public class MainViewModel : ViewModelBase
{
    public ObservableCollection<HealthDisease> EntityList { get; set; }
    public MainViewModel()
    {
        RetrieveMany();
    }
    private void RetrieveMany()
    {
        EntityList = new ObservableCollection<HealthDisease>
        {
            new HealthDisease {Name = "Disease A"},
            new HealthDisease {Name = "Disease B"},
            new HealthDisease {Name = "Disease C"}
        };
    }
    private HealthDisease highlighted;
    public HealthDisease Highlighted
    {
        get { return highlighted; }
        set
        {
            highlighted = value;
            OnPropertyChanged();
            OnPropertyChanged("HighlightedName");
        }
    }
    public string HighlightedName
    {
        get { return Highlighted == null ? string.Empty : Highlighted.Name; }
    }
}