首页 > 解决方案 > 在这种情况下,如何将 C# 类参数的值绑定到 XAML 组件?

问题描述

我正在尝试学习 C# 中的数据绑定和新功能。为了将代码与 UI 隔离,我想绑定 XAML 中的值。我做了下面的例子来尽可能清楚地问我的问题:

这是程序。我希望通过使用增加或减少按钮来增加或减少进度条,但这些应该与类中的“值”参数相关联。Power 类中的 increaseValue 方法返回值,我想将该值绑定到按钮和进度条。因此,当用户单击按钮时,该值将增加,并且进度条将与新值相关联:

在此处输入图像描述

XAML 代码:

<Window x:Class="WpfBindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfBindingTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>

        <Button x:Name="Increase" Content="Increase" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Button>
        <Button  Grid.Row="1" x:Name="Decrease" Content="Decrease" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Button>
        <ProgressBar Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Height="10"></ProgressBar>
        <Label Grid.Row="1" Grid.Column="1"  HorizontalAlignment="Stretch" VerticalAlignment="Center"></Label>
        
    </Grid>
</Window>

MainWindow.xaml.cs:

namespace WpfBindingTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Power power = new Power();
        public MainWindow()
        {
            InitializeComponent();          
        }
    }
}

等级功率:

namespace WpfBindingTest
{
    public class Power
    {

        public int increaseValue(int value)
        {
            value++;
            return value;
        }
    }
}

我可以通过代码实现我想要的,但我想将 Power 类与 UI 隔离,但对如何进行数据绑定感到非常困惑。

标签: c#wpfdata-binding

解决方案


我目前无法测试我的答案,所以请谨慎对待:

首先,如果要绑定到 Power 类,则必须在 MainWindow.xaml.cs 中将其设置为 Datacontext:

namespace WpfBindingTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Power power = new Power();
        DataContext = power;
        public MainWindow()
        {
            InitializeComponent();          
        }
    }
}

然后将继承自 ICommand 的 RelaisCommand 类添加到您的项目中(您可以简单地复制以下代码:

public class RelayCommand : ICommand
    {
        #region Private Fields
        private readonly Action<object> _executeHandler;
        private readonly Predicate<object> _canExecuteHandler;
        #endregion

        #region Constructors
        public RelayCommand(Action<object> execute) : this(execute, null)
        {
        
        }
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("Execute cannot be 'null'!");
            _executeHandler = execute;
            _canExecuteHandler = canExecute;
        }
        #endregion

        #region public Methods
        public void Execute(object parameter)
        {
            _executeHandler(parameter);
        }
        public bool CanExecute(object parameter)
        {
            if (_canExecuteHandler == null) return true;
            return _canExecuteHandler(parameter);
        }
        #endregion

        #region Events
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        #endregion

    }

在您的 Power 类中,您可以添加一个 Binding 属性,如下所示:

public class Power
{

    ICommand increaseValueCommand;
    int value = 0;

    /// <summary>
    /// Command to increase value
    /// </summary>
    public ICommand IncreaseValueCommand
    {
        get
        {
            return increaseValueCommand?? (increaseValueCommand= new RelayCommand(command => increaseValue()));
        }
    }

    public void increaseValue()
    {
        value++;
    }
}

在您的 xaml 中,您应该能够将按钮命令绑定到您的 ICommand 接口:

<Button x:Name="Increase" Content="Increase" Horizo​​ntalAlignment="Stretch" VerticalAlignment="Stretch" Command={Binding increaseValueCommand}>

请记住,虽然这会将 Button 命令绑定到您的 ICommand 接口,该接口随后将执行您的increaseValue()方法,但如果您想将value(我将其更改为 Power 类的私有属性)绑定到 Progressbar,您将不得不实现INotifyPropertyChanged接口。这是如何完成的,我的 MVVM 示例也显示在上面评论中链接的 repo 中。


推荐阅读