组合框绑定MVVM C#

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合框绑定MVVM C#相关的知识,希望对你有一定的参考价值。

我错过了什么,但我不知道是什么:(

我将IEnumerable集合绑定到组合框。我想使用其选定的值作为shutdown命令的参数,但是当我按下开始按钮时,它不会加载选定的值。

我已经遵循了一些教程来理解MVVM,但仍然有一些缺失,但我无法弄清楚是什么。

这是MainWindow.xaml:

<grid>
    <StackPanel>
        <!--Title label-->
        <TextBlock Text="Wyłącz komputer za:" Margin="5"/>

        <!-- Blocks used to set hours and minutes-->
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Godziny:" Margin="5"/>
            <ComboBox x:Name="HoursCB" Margin="5" Width="40" ItemsSource="{Binding myHours}" SelectedValue="{Binding selectedHours, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="Minuty:" Margin="5" />
            <ComboBox x:Name="MinutesCB" Margin="5" Width="40" ItemsSource="{Binding myMinutes}" SelectedValue="{Binding selectedMinutes, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel >

        <!-- Timer -->
        <StackPanel Orientation="Horizontal">
            <Label x:Name="HHLabel" Content="{Binding selectedHours}" FontSize="30" HorizontalAlignment="Center" Width="45"/>
            <Label x:Name="Colon1" Content=":" FontSize="30" HorizontalAlignment="Center" Width="25"/>
            <Label x:Name="MMLabel" Content="{Binding selectedMinutes}" FontSize="30" HorizontalAlignment="Center" Width="45"/>
            <Label x:Name="Colon2" Content=":" FontSize="30" HorizontalAlignment="Center" Width="25"/>
            <Label x:Name="SSLabel" Content="00" FontSize="30" HorizontalAlignment="Right" Width="45"/>
        </StackPanel>

        <!-- Start Button -->
        <Button Content="uruchom odliczanie" Margin="5" Command="{Binding StartCommand}" />

        <!-- Stop Button-->
        <Button Content="Zatrzymaj odliczanie" Margin="5" Command="{Binding StopCommand}"/>
    </StackPanel>
</grid>

这是视图模型:

class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        StartCommand = new AddNameCommand(this);
    }

    class AddNameCommand : ICommand
    {
        MainWindowViewModel parent;

        public AddNameCommand(MainWindowViewModel parent)
        {
            this.parent = parent;
            parent.PropertyChanged += delegate { CanExecuteChanged?.Invoke(this, EventArgs.Empty); };
        }

        public event EventHandler CanExecuteChanged;

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

        public void Execute(object parameter)
        {
            int num = parent.SelectedHours * 3600 + parent.SelectedMinutes * 60;
            MessageBox.Show($"Shutting down the computer in {num} !");
            //Process.Start("shutdown", string.Format("/s /t {0}", num));
        }
    }

    public ICommand StartCommand { get; private set; }


    /// <summary>
    /// Combobox Items.
    /// </summary>
    //public IEnumerable<int> myHours = Enumerable.Range(0, 23);
    //public IEnumerable<int> myMinutes = Enumerable.Range(1, 59);
    public ObservableCollection<int> myHours { get; set; } = new ObservableCollection<int>(Enumerable.Range(0, 23));
    public ObservableCollection<int> myMinutes { get; set; } = new ObservableCollection<int>(Enumerable.Range(1, 59));


    /// <summary>
    /// Selected time properties.
    /// </summary>
    public int SelectedMinutes
    {
        get { return mSelectedMinutes; }
        set
        {
            if (value == mSelectedMinutes)
                return;
            mSelectedMinutes = value;
            OnPropertyChanged();
        }
    }
    int mSelectedMinutes;

    public int SelectedHours
    {
        get { return mSelectedHours; }
        set
        {
            if (value == mSelectedHours)
                return;
            mSelectedHours = value;
            OnPropertyChanged();
        }
    }
    int mSelectedHours;

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName]string propertyName = null)
    { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
}
答案

您应该将xaml更改为以下内容(请注意区分大小写的SelectedHours / Minutes):

    <!-- Blocks used to set hours and minutes-->
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Godziny:" Margin="5"/>
        <ComboBox x:Name="HoursCB" Margin="5" Width="40" ItemsSource="{Binding myHours}" SelectedValue="{Binding SelectedHours, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="Minuty:" Margin="5" />
        <ComboBox x:Name="MinutesCB" Margin="5" Width="40" ItemsSource="{Binding myMinutes}" SelectedValue="{Binding SelectedMinutes, UpdateSourceTrigger=PropertyChanged}" />
    </StackPanel >

通过打开Output Window中的Visual Studio并查找以下内容,可以轻松检测到绑定错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'selectedHours' property not found on 'object' ''MainWindowViewModel' (HashCode=46431654)'. BindingExpression:Path=selectedHours; DataItem='MainWindowViewModel' (HashCode=46431654); target element is 'ComboBox' (Name='HoursCB'); target property is 'SelectedValue' (type 'Object')
另一答案

您尚未将组合框的选定值绑定到视图模型中的右侧属性。只需在XAML中将“selectedHours”更改为“SelectedHours”,将“selectedMinutes”更改为“SelectedMinutes”即可正确绑定它。

另一答案

enter image description here

你的代码表现得像我预期的那样。你的问题是Enumerable.Range功能。它以包含0开始,然后向上计数23次,包括0

以上是关于组合框绑定MVVM C#的主要内容,如果未能解决你的问题,请参考以下文章

在 MVVM 中的 Datagrid 中绑定 WPF 组合框不保存更改

在 WPF / C# 中选择绑定项目后维护组合框文本

Kendo网格在网格中触发多个控件的数据源事件。(MVVM绑定)

窗口加载时WPF级联组合框不绑定

WPF MVVM 将 ComboBox 绑定到 Datagrid 选定项

使用 MVVM 和数据绑定更改每个片段中的工具栏标题