将方法从后面的代码转换为 ICommand 数据绑定 Xamarin.Forms
Posted
技术标签:
【中文标题】将方法从后面的代码转换为 ICommand 数据绑定 Xamarin.Forms【英文标题】:Convert methods from code behind to ICommand Databinding Xamarin.Forms 【发布时间】:2022-01-10 16:50:45 【问题描述】:我在 Xamarin.Forms 中有一个计算器应用程序,我想实现 MVVM。现在,在拥有 MVVM 文件夹之前,我在 MainPage.xaml.cs 中创建了方法。创建 ViewModel 文件夹时,我将 MainPage.xaml.cs 中的每个代码都放入 Methods.cs,而不更改方法本身。当然,“resultText”在当前上下文中是不存在的,所以我在网上深入搜索,发现我需要ICommand接口。我搜索了几个小时来了解如何为我的代码实现接口,但它对我来说太复杂了,我一个字都听不懂,浪费了几个小时看数百个教程,但我的大脑无法接受有关如何实现它的信息在我的代码中。我唯一做的就是把 : ICommand 放在类名之后,所以它在我的代码中生成了 2 个方法和 1 个事件,仅此而已,我不知道如何继续。有什么想法吗?
Methods.cs:
namespace Calculator.ViewModel
class Methods : ICommand
private decimal firstNumber;
private string operatorName;
private bool isOperatorClicked;
public event EventHandler CanExecuteChanged;
//public event PropertyChangedEventHandler PropertyChanged;
public void OnNumberButton_Clicked(object sender, EventArgs e)
var button = sender as Button;
if (resultText.Text == "0" || isOperatorClicked)
isOperatorClicked = false;
resultText.Text = button.Text;
else
resultText.Text += button.Text;
public void OnClearButton_Clicked(object sender, EventArgs e)
resultText.Text = "0";
public void OnOperationButton_Clicked(object sender, EventArgs e)
var button = sender as Button;
isOperatorClicked = true;
operatorName = button.Text;
firstNumber = Convert.ToDecimal(resultText.Text);
public void OnEqualButton_Clicked(object sender, EventArgs e)
try
decimal secondNumber = Convert.ToDecimal(resultText.Text);
string finalResult = Calculate(firstNumber, secondNumber).ToString("0.##");
resultText.Text = finalResult;
catch (Exception)
throw;
public decimal Calculate(decimal firstNumber, decimal secondNumber)
decimal result = 0;
if (operatorName == "+")
result = firstNumber + secondNumber;
else if (operatorName == "-")
result = firstNumber - secondNumber;
else if (operatorName == "*")
result = firstNumber * secondNumber;
else if (operatorName == "/")
result = firstNumber / secondNumber;
return result;
public bool CanExecute(object parameter)
return true;
public void Execute(object parameter)
OnClearButton_Clicked;
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Calculator.MainPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="android" Value="20, 20" > </On>
</OnPlatform>
</ContentPage.Padding>
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="infostyle" TargetType="Button">
<Setter Property="WidthRequest" Value="60"/>
<Setter Property="HeightRequest" Value="60"/>
<Setter Property="TextColor" Value="White"/>
<Setter Property="FontSize" Value="25"/>
<Setter Property="BorderColor" Value="Black"/>
<Setter Property="BorderWidth" Value="1"/>
<Setter Property="BackgroundColor" Value="Green"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="topstyle" TargetType="Button">
<Setter Property="WidthRequest" Value="60"/>
<Setter Property="HeightRequest" Value="60"/>
<Setter Property="TextColor" Value="White"/>
<Setter Property="FontSize" Value="25"/>
<Setter Property="BorderColor" Value="Black"/>
<Setter Property="BorderWidth" Value="1"/>
<Setter Property="BackgroundColor" Value="Green"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="rightstyle" TargetType="Button">
<Setter Property="WidthRequest" Value="60"/>
<Setter Property="HeightRequest" Value="60"/>
<Setter Property="TextColor" Value="White"/>
<Setter Property="FontSize" Value="25"/>
<Setter Property="BorderColor" Value="Black"/>
<Setter Property="BorderWidth" Value="1"/>
<Setter Property="BackgroundColor" Value="Red"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="resultstyle" TargetType="Button">
<Setter Property="FontAttributes" Value="Bold"/>
<Setter Property="TextColor" Value="Black"/>
<Setter Property="FontSize" Value="38"/>
<Setter Property="HorizontalOptions" Value="End"/>
<Setter Property="VerticalOptions" Value="Center"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Grid Padding="0, 0" RowSpacing="10" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ContentView Padding="0, 0, 20, 0" Margin="0, 0, 0, 10" Grid.ColumnSpan="4" BackgroundColor="Brown">
<Label x:Name="resultText" Text="0" Style="StaticResource resultstyle">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android">
</On>
</OnPlatform>
</Label.FontFamily>
</Label>
</ContentView>
<Button Text="C" x:Name="btnClear" Grid.Column="0" Grid.Row="1" Style="StaticResource topstyle" Clicked="Binding OnClearButton_Clicked"/>
<Button x:Name="btnSave" Grid.Column="1" Grid.Row="1" Text="⎚" Style="StaticResource topstyle"/>
<Button Text="/" Grid.Column="2" Grid.Row="1" Style="StaticResource topstyle" Clicked= "Binding OnOperationButton_Clicked"/>
<Button Text="÷" Grid.Column="3" Grid.Row="1" Style="StaticResource rightstyle"/>
<Button Text="7" Grid.Column="0" Grid.Row="2" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="8" Grid.Column="1" Grid.Row="2" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="9" Grid.Column="2" Grid.Row="2" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="*" Grid.Column="3" Grid.Row="2" Style="StaticResource rightstyle" Clicked="Binding OnOperationButton_Clicked"/>
<Button Text="4" Grid.Column="0" Grid.Row="3" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="5" Grid.Column="1" Grid.Row="3" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="6" Grid.Column="2" Grid.Row="3" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="-" Grid.Column="3" Grid.Row="3" Style="StaticResource rightstyle" Clicked="Binding OnOperationButton_Clicked"/>
<Button Text="1" Grid.Column="0" Grid.Row="4" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="2" Grid.Column="1" Grid.Row="4" Style="StaticResource infostyle" Clicked="Binding OnNumberButton_Clicked"/>
<Button Text="3" Grid.Column="2" Grid.Row="4" Style="StaticResource infostyle" Clicked="Binding OnNumberButton_Clicked"/>
<Button Text="+" Grid.Column="3" Grid.Row="4" Grid.RowSpan="2" Style="StaticResource rightstyle" Clicked="Binding OnOperationButton_Clicked"/>
<Button Text="." Grid.Column="0" Grid.Row="5" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button Text="0" Grid.Column="1" Grid.Row="5" Style="StaticResource infostyle" Clicked= "Binding OnNumberButton_Clicked"/>
<Button x:Name="btnEqual" Text="=" Grid.Column="2" Grid.Row="5" Style="StaticResource infostyle" Clicked= "Binding OnEqualButton_Clicked"/>
</Grid>
MainPage.xaml.cs:
namespace Calculator
public partial class MainPage : ContentPage
public MainPage()
InitializeComponent();
BindingContext = new Methods();
我很想以某种方式转换方法(如 OnEqualButton_Clicked 或 OnClearButton_Clicked 成为可绑定命令
【问题讨论】:
这里是一个示例 MVVM 计算器,可以为您提供一些想法 - github.com/LeanManager/Xamarin.Forms-MVVM-Calculator。 去掉你添加到类方法中的: ICommand
。然后按照 Jason 的建议去做 - 尝试一个有效的 MVVM 示例,直到你掌握发生了什么。了解这些细节: 1) 将 BindingContext 设置为 VM 类的实例。 2) resultText
应该如何绑定到 VM 类中的公共属性。 3)每个按钮应该如何绑定到VM类中对应的Command
公共属性。 4) 在 VM 类的构造函数中放入什么来初始化命令。
an MVVM example。 Another MVVM example.
【参考方案1】:
你需要创建一个viewmodel来绑定bindingcontext,在构造函数中初始化命令like(代码来自xamarin文档):
class CommandDemoViewModel : INotifyPropertyChanged
double number = 1;
public event PropertyChangedEventHandler PropertyChanged;
public CommandDemoViewModel()
MultiplyBy2Command = new Command(() => Number *= 2);
DivideBy2Command = new Command(() => Number /= 2);
public double Number
set
if (number != value)
number = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Number"));
get
return number;
public ICommand MultiplyBy2Command private set; get;
public ICommand DivideBy2Command private set; get;
以下是文档及其示例:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/button
https://docs.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/userinterface-buttondemos/
【讨论】:
以上是关于将方法从后面的代码转换为 ICommand 数据绑定 Xamarin.Forms的主要内容,如果未能解决你的问题,请参考以下文章
如何在 WPF 中使用 ICommand 中的 CanExecute 方法