在 WPF Prism MVVM 的 VM 中设置和显示 ComboBox 中的 SelectedItem

Setting and Showing the SelectedItem in ComboBox from VM in WPF Prism MVVM

我正在尝试从我的 VM 中设置 ComboBox SelectedItem。我想我很接近,但我不知道如何在从 VM 设置时在 ComboBox 中显示 SelectedItem。

文本框绑定到 SelectedItem 属性。当我 运行 它时,它确实会在我的文本框中显示星期五,但组合框仍然是空的。 TextBox 还在我的 ComboBox 中显示我可能 select 的任何值,所以我认为我已经完成了这部分。我需要更改什么才能在 ComboBox 中显示它?不确定我在代码中犯了错误,还是我只是需要做一些老实说我不知道​​的事情。

示例数据库是 WeekDays

WeekDayID    WeekDayShort   WeekDayLong
    1            Sun          Sunday
    2            Mon          Monday
    3            Tue          Tuesday
    4            Wed          Wednesday
    5            Thu          Thursday
    6            Fri          Friday
    7            Sat          Saturday

型号WeekDays.cs:

public partial class WeekDays
{
    public int WeekDayID { get; set; }
    public string WeekDayShort { get; set; }
    public string WeekDayLong { get; set; }
}

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        Initialize();
    }

    public void Initialize()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            SelectedWeekDay = (from a in nlt.WeekDays where a.WeekDayLong == "Friday" select a).Single();
        }
    }
}

和 View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedItem="{Binding SelectedWeekDay, Mode=TwoWay}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>

当你想 select ComboBox 中的一个项目通过其项目 class 的 属性 的值时,你应该设置 SelectedValueSelectedValuePath 属性而不是 SelectedItem:

<ComboBox ItemsSource="{Binding WeekDays}"
          DisplayMemberPath="WeekDayLong"
          SelectedValuePath="WeekDayLong"
          SelectedValue="{Binding SelectedWeekDay}"/>

在视图模型中,SelectedWeekDay 属性 不再是 WeekDay 实例,而只是一个字符串:

private string _selectedWeekDay;
public string SelectedWeekDay
{
    get { return _selectedWeekDay; }
    set { SetProperty(ref _selectedWeekDay, value); }
}

TextBox 绑定看起来像这样:

<TextBox Text="{Binding SelectedWeekDay, UpdateSourceTrigger=PropertyChanged}"/>

你当然会像这样在代码后面简单地设置它:

SelectedWeekDay = "Friday";

感谢 Clemens 在这里指导我正确的方向 2 个可能的答案对我有用。

解决方案 01:

继续使用 SelectedItem 并引入 SelectedIndex。

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private int _selectedIndex;
    public int SelectedIndex
    {
        get
        {
            return _selectedIndex;
        }
        set
        {
            SetProperty(ref _selectedIndex, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        SelectedIndex = 4;        
    }
}

还有 View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedItem="{Binding SelectedWeekDay}"
    SelectedIndex="{Binding SelectedIndex}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong}">
</TextBox>

解决方案02:

将 SelectedIndex 和 SelectedValue 与 SelectedValuePath 结合使用。

ViewModel MainViewModel.cs :

class MainViewModel : BindableBase
{
    private ObservableCollection<WeekDays> _weekDays;
    public ObservableCollection<WeekDays> WeekDays
    {
        get
        {
            return _weekDays;
        }
        set
        {
            SetProperty(ref _weekDays, value);
        }
    }

    private int _selectedIndex;
    public int SelectedIndex
    {
        get
        {
            return _selectedIndex;
        }
        set
        {
            SetProperty(ref _selectedIndex, value);
        }
    }

    private WeekDays _selectedWeekDay;
    public WeekDays SelectedWeekDay
    {
        get
        {
            return _selectedWeekDay;
        }
        set
        {
            SetProperty(ref _selectedWeekDay, value);
        }
    }

    private void FillWeekDays()
    {
        using (NLTrader01Entities nlt = new NLTrader01Entities())
        {
            var q = (from a in nlt.WeekDays select a).ToList();
            WeekDays = new ObservableCollection<WeekDays>(q);
        }
    }

    public MainViewModel()
    {
        FillWeekDays();
        SelectedIndex = 4;       
    }
}

还有 View.xaml :

<ComboBox
    ItemsSource="{Binding WeekDays}"
    DisplayMemberPath="WeekDayLong"
    SelectedValuePath="WeekDayLong"
    SelectedValue="{Binding SelectedWeekDay}"
    SelectedIndex="{Binding SelectedIndex}">
</ComboBox>
<TextBox
    Text="{Binding SelectedWeekDay.WeekDayLong}">
</TextBox>