查看页面标签未在xamarin中使用MVVM命令刷新

oipij1gg  于 2023-06-27  发布在  其他
关注(0)|答案(1)|浏览(76)

我在一个电子商务应用程序中有一个购物车页面。我有我的订单总价作为一个正常的标签在xamarin视图页面以外的数据模板在xaml代码如下所示。我在视图模型页面上有一个按钮,用于处理从购物车中删除产品的命令。我希望总订单和点标签更新时,从购物车中删除一个项目。
下面是我使用的代码
XAML

`<Button ImageSource="bin.png"
                                        x:Name="btnDelete"
                                        Command="{Binding Source={x:Reference cartCollectionView}, Path=BindingContext.CartsCommand}" 
                                        CommandParameter="{Binding .}"
                                        Clicked="btnDelete_Clicked"
                                        BackgroundColor="Transparent"
                                        HorizontalOptions="EndAndExpand"/>

                            </StackLayout>
                        </StackLayout>
                    </Frame>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    <StackLayout Orientation="Horizontal">
        <Label Text="Order #:"
               FontSize="20"
               TextColor="Black"/>
        <Label x:Name="txtOrderNumber"
              FontSize="20" 
               TextColor="Black"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal">
        <Label Text="Total Woof Bits earned:" FontSize="Title" Margin="0,0,0,0" TextColor="Black"/>
        <Label x:Name="txtPoints" Text="{Binding strPoints}" FontSize="Title" Margin="0,0,0,0" TextColor="Black"/>
    </StackLayout>

    <StackLayout Orientation="Horizontal">
        <Label Text="Total Order:" FontSize="Title" TextColor="Black"/>
        <Label  x:Name="txtTotalOrder" Text="{Binding strTotalOrder}" FontSize="Title" TextColor="Black"/>
    </StackLayout>`

查看

`public CartPage(CartViewModel viewModels)
    {
        InitializeComponent();
        BindingContext = viewModels;
        BindingContext = new CartViewModel();
        ((CartViewModel)BindingContext).LoadCartsCommand.Execute(null);
        ((CartViewModel)BindingContext).LoadTotalsCommand.Execute(null);

        txtOrderNumber.Text = SigninPage.strOrderNumber;
        txtPoints.Text = CartViewModel.strPoints;
        txtTotalOrder.Text = CartViewModel.strTotalOrder;
        
        
    }

    

    protected override void OnAppearing()
    {
        base.OnAppearing();

        ((CartViewModel)BindingContext).LoadCartsCommand.Execute(null);
        ((CartViewModel)BindingContext).LoadTotalsCommand.Execute(null);
        txtPoints.Text = CartViewModel.strPoints;
        txtTotalOrder.Text = CartViewModel.strTotalOrder;
        
    }
    
    

    private void Button_Clicked(object sender, EventArgs e)
    {
        
        ((CartViewModel)BindingContext).PayCommand.Execute(null);
        
    }

    private void btnDelete_Clicked(object sender, EventArgs e)
    {
        ((CartViewModel)BindingContext).LoadTotalsCommand.Execute(null);

        txtPoints.Text = CartViewModel.strPoints;
        txtTotalOrder.Text = CartViewModel.strTotalOrder;
        DisplayAlert("Successful", "Item removed from Cart (▼´•̥ᴥ•̥`) ", "OK");
    }`

视图模型

`private ICommand _loadTotalsCommand;

    public ICommand LoadTotalsCommand
    {
        get
        {
            if (_loadTotalsCommand == null)
            {
                _loadTotalsCommand = new Command(async () => await LoadTotals());
                OnPropertyChanged();
            }

            return _loadTotalsCommand;
        }
    }

    public async Task LoadTotals()
    {
        string sqlstring = "MySQL string";
        MySqlConnection mysqlcon = new MySqlConnection(sqlstring);
        MySqlCommand mysqlcom;
        MySqlDataReader mdr;

        mysqlcon.Open();

        string selectquery = "SELECT ordernumber, quantity, price, sum(price * quantity) AS Total, sum(pointvalue) AS Total1 FROM cart WHERE ordernumber = '" + SigninPage.strOrderNumber + "' GROUP BY ordernumber;";
        mysqlcom = new MySqlCommand(selectquery, mysqlcon);

        mdr = mysqlcom.ExecuteReader();

        while (mdr.Read())
            if (mdr.FieldCount >= 1)
            {
                TotalOrder = mdr.GetDecimal(3);
                Points = mdr.GetDecimal(4);
            }


        mysqlcon.Close();
        strTotalOrder = "R" + Convert.ToString(TotalOrder);
        strPoints = "🐾" + Convert.ToString(Points);

    }


    private ICommand _cartCommand;

    public ICommand CartsCommand
    {
        get
        {
            if (_cartCommand == null)
            {
                _cartCommand = new Command<Cart>(async (cart) =>
                {
                    await OnCartSelected(cart);
                });
            }

            return _cartCommand;
        }
    }

    


    public async Task OnCartSelected(Cart cart)
    {

        // Navigate to the ProductDetailsPage and pass the selected product as a parameter
        string constring5 = "MySQL string";
        MySqlConnection con5 = new MySqlConnection(constring5);
        con5.Open();
        MySqlTransaction transaction5 = con5.BeginTransaction();

        using (MySqlCommand cmd5 = new MySqlCommand("DELETE FROM cart WHERE ordernumber = '" + strOrderNumber4 + "'", con5))
        {
            cmd5.Transaction = transaction5;

            cmd5.ExecuteNonQuery();
            transaction5.Commit();
            con5.Close();
        }

       
        LoadTotalsCommand.Execute(null);
        LoadCartsCommand.Execute(null);
        

    }`
pbgvytdp

pbgvytdp1#

更新

您不必在xaml中为选项卡式页面设置ViewModel。把它放在.cs文件中就足够了。你可以试试下面的代码:
对于选项卡页面:

<NavigationPage Title="Cart" IconImageSource="cart.png">
    <x:Arguments>
        <local:CartPage Title="Cart">
        </local:CartPage>
    </x:Arguments>
</NavigationPage>

在CartPage.cs中

public partial class CartPage : ContentPage
{
    CartViewModel ViewModel;
    public CartPage()
    {
        InitializeComponent();
        ViewModel = new CartViewModel();
        BindingContext = ViewModel;

    }

更新
1.要使用RadioButton,您可以尝试以下方法:

In .xaml

<RadioButton BorderColor="Red" Content="Collect" Value="Collect" CheckedChanged="RadioButton_CheckedChanged"/>
<RadioButton x:Name="Delivery" Content="Delivery" CheckedChanged="RadioButton_CheckedChanged"/>

在.cs文件中

public partial class CartPage : ContentPage
{
    CartViewModel ViewModel;
    public CartPage(CartViewModel viewModels)
    {
        InitializeComponent();
        ViewModel = viewModels;
        BindingContext = ViewModel;

    }

    async void RadioButton_CheckedChanged(System.Object sender, Xamarin.Forms.CheckedChangedEventArgs e)
    {
        RadioButton r = sender as RadioButton;
        if((string)(r.Content) == "Delivery" && r.IsChecked)
        {
            viewModel.TotalOrder += 50;

        }
        if((string)(r.Content) == "Collect" && r.IsChecked)
        {
            await DisplayAlert("Alert", "You have been alerted", "OK");

        }
    }
}

2.改变颜色

如果使用Android,则可以使用Custom Renderer
1.在共享项目中创建自己的自定义RadioButton:

public class MyRadioButton : RadioButton
{
    public MyRadioButton()
    {
    }
}

2.然后在YourProject.Android文件夹中创建MyRadioButtonRenderer.cs

[assembly: ExportRenderer(typeof(MyRadioButton), typeof(MyRadioButtonRenderer))]
namespace ViewPageLabelNotRefreshing76512008.Droid
{
    public class MyRadioButtonRenderer : RadioButtonRenderer
    {
        public MyRadioButtonRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<RadioButton> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.ButtonTintList = ColorStateList.ValueOf(Android.Graphics.Color.ForestGreen);
            }
        }
    }
}

3.在XAML中使用它

<ContentPage
...
    xmlns:local="clr-namespace:ViewPageLabelRefreshing">

<local:MyRadioButton x:Name="Delivery" Content="Delivery" CheckedChanged="RadioButton_CheckedChanged"/>

===============================
我根据你的代码做了一些修改。你的项目很长,我只关注了这个问题删除命令部分。我没有对paycommand部分进行更改。所以在xaml中,我只是注解掉了以下部分:

<!--<RadioButton Content="Collect" Value="Collect" CheckedChanged="RadioButton_CheckedChanged"/>
    <RadioButton x:Name="Delivery" Content=""/>
    <Button Text="Fulfill Your Pets Wishlist"
            CornerRadius="20"
            BackgroundColor="Transparent"
            BorderColor="ForestGreen"
            BorderWidth="1.5"
            Clicked="Button_Clicked"
            />-->

我让CartPage.cs文件更容易(因为我们使用了mvvm方式):

public partial class CartPage : ContentPage
{
    public CartPage()
    {
        InitializeComponent();
        this.BindingContext = new CartViewModel();
    }
}

然后在CartViewModel

public class CartViewModel : INotifyPropertyChanged
{
    //define some variable or constant. No need to show them here
    ...

    //I add these two properties and implement OnPropertyChanged
    private string _strPoints;
    public string strPoints
    {
        get
        {
            return _strPoints;
        }
        set
        {
            _strPoints = value;
            OnPropertyChanged(nameof(strPoints));
        }
    }

    private string _strTotalOrder;
    public string strTotalOrder
    {
        get
        {
            return _strTotalOrder;
        }
        set
        {
            _strTotalOrder = value;
            OnPropertyChanged(nameof(strTotalOrder));
        }
    }

    //for  Carts you can just define like this
    public ObservableCollection<Cart> Carts { get; set; } = new ObservableCollection<Cart>();

    public CartViewModel()
    {
        //instead of execute in page.cs OnAppearing, you can just
        //execute the command in constructor
        LoadCartsCommand.Execute(null);
        LoadTotalsCommand.Execute(null);
    }

    private ICommand _loadCartsCommand;
    public ICommand LoadCartsCommand
    {
        get
        {
            if (_loadCartsCommand == null)
            {
                _loadCartsCommand = new Command(() => LoadCarts());
            }

            return _loadCartsCommand;
        }
    }

    public void LoadCarts()
    {
        // Call the GetCategories method to load the categories from the database
        GetCarts();
    }

    private ICommand _loadTotalsCommand;
    public ICommand LoadTotalsCommand
    {
        get
        {
            if (_loadTotalsCommand == null)
            {
                _loadTotalsCommand = new Command(() => LoadTotals());
                OnPropertyChanged();
            }

            return _loadTotalsCommand;
        }
    }

    // Method for getting the categories from the database
    private void GetCarts()
    {
        //In this method, you could add each Cart instance into Carts collection just as your code. In my demo, I just add some test data. Also to reduce code not show here.
        ...
    }

    public void LoadTotals()
    {
        //You make some calculation here, just as your code
        ...
    }

    private ICommand _cartCommand;

    public ICommand CartsCommand
    {
        get
        {
            if (_cartCommand == null)
            {
                _cartCommand = new Command<Cart>(async (cart) =>
                {
                    await OnCartSelected(cart);
                });
            }
            return _cartCommand;
        }
    }

    public async Task OnCartSelected(Cart cart)
    {
        // You should do these things
        // 1.First you should remove the this deleted cart in Carts collection.(The UI also refresh automatically) you could simply use the following: 
        Carts.Remove(cart);

        //2.Delete the cart in your mysql.  shouldn't it be DELETE FROM cart WHERE ordernumber =  strOrderNumber4 and name = cart.Name?
        //3. recalculation as the mysql has changed
        LoadTotalsCommand.Execute(null);
    }

......
}

希望能帮上忙!

相关问题