我想创建一个自定义命令控件来处理数量控制使用一个条目和2个按钮
我有一个mvvm页面,标签和按钮显示在视图模型数据模板中,我的按钮工作,它们改变了从mysql数据库中提取的数据,但它没有更新数量控制(条目)的可视端。
public class ProductDetailsViewModel : BaseProductDetailsViewModel
{
public string strOrderNumber3 = SigninPage.strOrderNumber;
public string strEmail1 = SigninPage.strEmail;
private string _productname;
public string QuantityNew1 = string.Empty;
private ICommand _quantityaddCommand;
public ICommand QuantityAddCommand
{
get
{
if (_quantityaddCommand == null)
{
_quantityaddCommand = new Command<ProductDetail>(async (productdetail) =>
{
await OnQuantityAddSelected(productdetail);
});
}
return _quantityaddCommand;
}
}
private async Task OnQuantityAddSelected(ProductDetail productdetail)
{
productdetail.Quantity = (Convert.ToInt32(productdetail.QuantityOld) + Convert.ToInt32(1)).ToString();
productdetail.QuantityOld = productdetail.Quantity;
OnPropertyChanged(productdetail.QuantityOld);
RefreshCanExcutes();
}
private ICommand _quantityminusCommand;
public ICommand QuantityMinusCommand
{
get
{
if (_quantityminusCommand == null)
{
_quantityminusCommand = new Command<ProductDetail>(async (productdetail) =>
{
await OnQuantityMinusSelected(productdetail);
});
}
return _quantityminusCommand;
}
}
private async Task OnQuantityMinusSelected(ProductDetail productdetail)
{
if (productdetail.Quantity != "0")
{
productdetail.Quantity = (Convert.ToInt32(productdetail.QuantityOld) - Convert.ToInt32(1)).ToString();
productdetail.QuantityOld = productdetail.Quantity;
OnPropertyChanged("productdetail.QuantityOld");
RefreshCanExcutes();
}
}
private void RefreshCanExcutes()
{
(QuantityAddCommand as Command).ChangeCanExecute();
(QuantityMinusCommand as Command).ChangeCanExecute();
}
public string ProductName
{
get { return _productname; }
set { _productname = value; }
}
public ProductDetailsViewModel(string productparamter)
{
_productname = productparamter;
}
private ICommand _loadProductDetailsCommand;
public ICommand LoadProductDetailsCommand
{
get
{
if (_loadProductDetailsCommand == null)
{
_loadProductDetailsCommand = new Command(async () => await LoadProductDetails());
}
return _loadProductDetailsCommand;
}
}
private List<ProductDetail> _productdetails;
public List<ProductDetail> ProductDetails
{
get => _productdetails;
set => SetProperty(ref _productdetails, value);
}
public async Task LoadProductDetails()
{
// Call the GetCategories method to load the categories from the database
ProductDetails = await GetProductDetails();
}
// Method for downloading an image
private async Task<byte[]> DownloadImageAsync(string url)
{
using (var httpClient = new HttpClient())
{
return await httpClient.GetByteArrayAsync(url);
}
}
// Method for getting the categories from the database
private async Task<List<ProductDetail>> GetProductDetails()
{
// Initialize the list of categories
List<ProductDetail> productdetails = new List<ProductDetail>();
// Connect to the database
using (MySqlConnection connection = new MySqlConnection("mysql string"))
{
connection.Open();
// Create a command to select the categories from the database
using (MySqlCommand command = new MySqlCommand("SELECT name, productdetails, price, image, quantity FROM products WHERE name = '" + ProductName + "' ", connection))
{
// Execute the command and read the results
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (reader.FieldCount >= 5)
{
// Create a new category object
ProductDetail productdetail = new ProductDetail
{
Name = reader.GetString(0),
ProductDetails = reader.GetString(1),
Price = "R " + reader.GetString(2),
Price1 = reader.GetString(2),
ImageUrl = reader.GetString(3),
Quantity = reader.GetString(4),
QuantityOld = reader.GetString(4),
};
// Download the image for the category
productdetail.ImageData = await DownloadImageAsync(productdetail.ImageUrl);
// Add the category to the list
productdetails.Add(productdetail);
}
}
}
}
}
// Return the list of categories
return productdetails;
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App2.Views.ProductDetails"
BackgroundImageSource="bckgrnd20Darken.jpg"
>
<StackLayout Padding="10">
<Entry x:Name="txtQuantity" IsReadOnly="True" BindingContext="{Binding Quantity, Mode=OneWayToSource}"/>
<Entry x:Name="txtQuantityOld" IsReadOnly="True"/>
<Label x:Name="txtOrderNumber"/>
<CollectionView x:Name="productdetailsCollectionView" ItemsSource="{Binding ProductDetails}" >
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="1" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout HorizontalOptions="Center" VerticalOptions="CenterAndExpand" Margin="0" Padding="7" >
<Frame HasShadow="False" BorderColor="Black" BackgroundColor="Transparent" CornerRadius="20">
<StackLayout Padding="5">
<Image Source="{Binding ImageUrl}" HeightRequest="200" />
<Label Text="{Binding Name}" FontSize="Title" FontAttributes="Bold" HorizontalTextAlignment="Center" TextColor="Black" Padding="10" />
<Label Text="About This Product" FontSize="Large" FontAttributes="Bold" Margin="10,10,10,10" TextColor="Black"/>
<Label Text="{Binding ProductDetails}" Margin="10,10,10,10" FontSize="Large" HorizontalTextAlignment="Start" VerticalTextAlignment="Center" TextColor="White"/>
<Label Text="{Binding Price}" Margin="10,10,10,10" FontSize="Title" FontAttributes="Bold" TextColor="Black" />
<Label Text="{Binding Price1}" IsVisible="false"/>
<StackLayout Orientation="Horizontal">
<Button
x:Name="minusbutton"
ImageSource="minus.png"
Command="{Binding Source={x:Reference productdetailsCollectionView}, Path=BindingContext.QuantityMinusCommand}"
CommandParameter="{Binding .}"
BackgroundColor="Transparent"/>
<Entry Text="{Binding Quantity}"/>
<Entry Text="{Binding QuantityOld}"/>
<Entry Text="{Binding QuantityNew, Mode=TwoWay}"/>
<Button
ImageSource="Plus.png"
Command="{Binding Source={x:Reference productdetailsCollectionView}, Path=BindingContext.QuantityAddCommand}"
CommandParameter="{Binding .}"
BackgroundColor="Transparent"/>
</StackLayout>
<Button
Command="{Binding Source={x:Reference productdetailsCollectionView}, Path=BindingContext.ProductDetailsCommand}"
CommandParameter="{Binding .}"
Text="ADD TO CART"
CornerRadius="20"
BackgroundColor="Blue"
TextColor="White"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
公共类BaseProductDetailsViewModel:INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
//protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
//{
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
//}
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
OnPropertyChanged(propertyName);
return true;
}
// Method for showing alerts
protected async Task ShowAlert(string title, string message, string buttonText)
{
await Application.Current.MainPage.DisplayAlert(title, message, buttonText);
}
}
public partial class ProductDetails : ContentPage
{
public static string strOrderNumber1 = SigninPage.strOrderNumber;
public ProductDetails(string ProductName)
{
InitializeComponent();
BindingContext = new ProductDetailsViewModel(ProductName);
// Call the method to load the categories from the database
((ProductDetailsViewModel)BindingContext).LoadProductDetailsCommand.Execute(null);
//txtQuantity.Text = strQuantity;
//txtQuantityOld.Text = strQuantityOld;
//txtQuantity.Text = txtQuantityOld.Text;
//txtQuantity.Text = "0";
//txtQuantityOld.Text = "0";
txtOrderNumber.Text = strOrderNumber1;
//strQuantity = txtQuantity.Text;
//strQuantityOld = txtQuantityOld.Text;
}
1条答案
按热度按时间cczfrluj1#
请重新检查您的型号
ProductDetail
是否实现了接口INotifyPropertyChanged
。从文档INotifyPropertyChanged Interface中,我们可以知道:
INotifyPropertyChanged接口用于通知客户端(通常是绑定客户端)属性值已更改。
基于你的代码,我创建了一个demo来实现这个功能.
可以参考以下代码:
ProductDetail.cs
TestViewModel.cs
使用示例:
注:
同时,您可以简化命令代码。
例如:
并在视图模型的构造函数上初始化这两个命令:
更新:
既然你已经为你的应用程序使用了MVVM,为什么你要在
ProductDetails.xmls.cs
页面中调用LoadProductDetailsCommand
命令?你可以删除它:
你可以在视图模型
ProductDetailsViewModel.cs
的构造函数上从数据库中获取数据,如下所示:此外,我建议您将
ProductDetails
的类型定义为ObservableCollection<T>
:在这种情况下,一旦向
ProductDetails
添加或删除项,UI将自行刷新。