Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Xamarin.Forms中实现INotifyPropertyChanged_C#_Xamarin_Xamarin.forms - Fatal编程技术网

C# 如何在Xamarin.Forms中实现INotifyPropertyChanged

C# 如何在Xamarin.Forms中实现INotifyPropertyChanged,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,我正在以Xamarin.Forms实现一个购物车。在我的购物车页面中有一个包含数据的列表视图。每个单元格都包含一个按钮,用于选择项目计数和金额。在购物车视图中有一个总计标签 我的问题是,当数字选择器更改时,总计没有更新。在添加视图单元时调用计算方法。我知道我需要为此实现INotifyProperty,但我不确定如何实现 我有一个基础视图模型,它继承了包含事件的INotifyProperty public class BaseViewModel : INotifyPropertyChanged

我正在以Xamarin.Forms实现一个购物车。在我的购物车页面中有一个包含数据的列表视图。每个单元格都包含一个按钮,用于选择项目计数和金额。在购物车视图中有一个总计标签

我的问题是,当数字选择器更改时,总计没有更新。在添加视图单元时调用计算方法。我知道我需要为此实现INotifyProperty,但我不确定如何实现

我有一个基础视图模型,它继承了包含事件的INotifyProperty

 public class BaseViewModel : INotifyPropertyChanged
{
    private double  _price;
    public double Price
    {
        get 
        { 
            return _price; 
        }
        set 
        { 
            _price = value;
            OnPropertyChanged("Price");}
        } 

 protected virtual void OnPropertyChanged(string propertyName)
 {
     if (PropertyChanged != null)
     {
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     }
 }
视图模型


例如,尝试以下视图模型:

public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetPropertyValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (value == null ? field != null : !value.Equals(field))
        {
            field = value;

            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
            return true;
        }
        return false;
    }
}

作为一种设计方法,最好将MVVM实现为一个子类,并将其实现到您的ViewModel中

示例实现:

我还强烈建议将ICommand实现为字典结构,如:

最后:Xaml用法:


当我开始Xamarin编码时,MVVM有点混乱,直到我发现ViewModel上的PropertyChangedEvent向ViewContentPage发出了一个信号,并更新了Label/textbox/etc

对于那些寻找“最新和最伟大”的人。。。下面是一些修改后的代码:

private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
在您的属性设置器上:

public string SomeProperty
{
    get { return _somProperty; }
    set
    {
       _someProperty= value;
            OnPropertyChanged();
        }
    }
}

很好?不省去了每次都要传递属性名的麻烦

请看一下这个样品。在这个存储库中,您可以找到MVVM模式和INotifyPropertyChanged接口的实现。现在可以了。我已经解决了问题,但我没有在视图中添加BindingContext。但现在我面临着其他类似的问题。我在列表视图中有+按钮,当我在购物车中添加项目时,图像必须更改为-。当我从购物车中删除项目时,图像再次更改为+。我希望在这里我也需要我的通知,但如何在这里实施。我现在有一个布尔属性,我的逻辑是:在添加和删除时更改布尔值,但我不知道如何将图像更改为按钮,哦,这里的一切都更有趣。你应该添加一个转换器,并像这样使用它:但这实际上是一个不同的问题。你能给我一个例子,这样我就可以检查它吗?我正在使用C进行设计UxBoolConvert的例子不适合回答注释,太多字符。创建一个单独的问题并在这里发布一个链接,我会把它放在一个答案中。我知道这是5年前的事了,但对于任何发现这一点的人来说,我不确定使用字典以这种方式实现ICommand是否是一种好的做法,因为它破坏了编译时绑定,在我看来这是一个很有价值的工具。@henda79您建议使用这种更改的解决方案是什么?@RandomNumberFun,你想达到什么目的?@henda79只是想找出关于你评论的最佳实践。
public class ObservableProperty : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
public abstract class ViewModelBase : ObservableProperty
{
    public Dictionary<string,ICommand> Commands { get; protected set; }

    public ViewModelBase()
    {
        Commands = new Dictionary<string,ICommand>();
    }
}
class LoginViewModel : ViewModelBase
{
    #region fields
    string userName;
    string password;
    #endregion

    #region properties
    public string UserName 
    {
         get {return userName;}
        set 
        {
            userName = value;
            OnPropertyChanged("UserName");
        }
     }

    public string Password 
    {
        get{return password;}
        set
        {
            password = value;
            OnPropertyChanged("Password");
        }
    }
    #endregion

    #region ctor
    public LoginViewModel()
    {
        //Add Commands
        Commands.Add("Login", new Command(CmdLogin));
    }
    #endregion


    #region UI methods

    private void CmdLogin()
    {
        // do your login jobs here
    }
    #endregion
}
<Entry Placeholder="Username"  Text="{Binding UserName}"/>
<Entry Placeholder="Password" Text="{Binding Password}" IsPassword="True"/>
<Button Text="Login" Command="{Binding Commands[Login]}"/>
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
public string SomeProperty
{
    get { return _somProperty; }
    set
    {
       _someProperty= value;
            OnPropertyChanged();
        }
    }
}