我正在尝试启用一个按钮,该按钮在输入绑定的属性嵌套字段时是绑定的,但即使所有属性都填充了数据,该按钮也被禁用。我应该改变什么?
这是我的基本视觉状态
public class BaseVisualState : Exrin.Framework.VisualState
{
public BaseVisualState() : this(null)
{
}
public BaseVisualState(IBaseModel i_Model) : base(i_Model)
{
PropertyObservable = Observable.FromEventPattern(
(EventHandler<PropertyChangedEventArgs> i_Event) => new PropertyChangedEventHandler(i_Event),
i_EventChanged => this.PropertyChanged += i_EventChanged,
i_EventChanged => this.PropertyChanged -= i_EventChanged);
}
public IObservable<EventPattern<PropertyChangedEventArgs>> PropertyObservable { get; private set; }
}我的视觉状态是
public class BeaconAddVisualState : BaseVisualState
{
private readonly IBeaconAddModel r_Model;
public BeaconAddVisualState(IBeaconAddModel i_Model)
: base(i_Model)
{
r_Model = i_Model;
}
[Binding(BindingType.TwoWay)]
public Beacon Beacon
{
get
{
return Get<Beacon>();
}
set
{
Set(value);
}
}
public override async void Init()
{
Beacon = new Beacon();
}
}信标类在属性更改时发出通知
public class Beacon : Document<Guid>, INotifyPropertyChanged
{
private string m_ProximityUuid;
private int? m_Major;
private int? m_Minor;
[Required]
public string ProximityUuid
{
get
{
return m_ProximityUuid;
}
set
{
if(m_ProximityUuid != value)
{
m_ProximityUuid = value;
notifyPropertyChanged();
}
}
}
[Required]
public int? Major
{
get
{
return m_Major;
}
set
{
if (m_Major != value)
{
m_Major = value;
notifyPropertyChanged();
}
}
}
[Required]
public int? Minor
{
get
{
return m_Minor;
}
set
{
if (m_Minor != value)
{
m_Minor = value;
notifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void notifyPropertyChanged([CallerMemberName] string i_PropertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(i_PropertyName));
}
}
}这是视图模型
public class BeaconAddViewModel : BaseAuthViewModel
{
private readonly IBeaconAddModel r_Model;
private readonly IDisposable r_Subscription;
public BeaconAddViewModel(IBeaconAddModel i_Model)
: base(new BeaconAddVisualState(i_Model))
{
r_Model = i_Model;
r_Subscription = State.PropertyObservable.Where(
i_Arg => i_Arg.EventArgs.PropertyName == nameof(State.Beacon.ProximityUuid)
|| i_Arg.EventArgs.PropertyName == nameof(State.Beacon.Major) || i_Arg.EventArgs.PropertyName == nameof(State.Beacon.Minor)).Subscribe(
i_Arg =>
{
AddCommand.OnCanExecuteChanged();
});
}
private BeaconAddVisualState State => VisualState as BeaconAddVisualState;
public override Task OnNavigated(object i_Args)
{
return base.OnNavigated(i_Args);
}
public IRelayCommand AddCommand
{
get
{
return GetCommand(
() =>
{
return new RelayCommand(
async (i_Parameter) =>
{
await r_Model.AddBeacon(i_Parameter as Beacon);
await NavigationService.Navigate("Beacons");
}, (i_Obj) => !string.IsNullOrEmpty(State.Beacon.ProximityUuid) && State.Beacon.Major.HasValue && State.Beacon.Minor.HasValue;
});
}
}
public override void Disposing()
{
base.Disposing();
r_Subscription?.Dispose();
}
}发布于 2017-08-21 12:10:09
这里的问题是,您在Beacon类中触发了INPC,但是BaseVisualState只查看Beacon (对象本身)是否发生了变化。
因此,您要么必须将属性带到Beacon之外,直接放入VisualState中,要么中继INPC事件。
例如,在你的Beacon do集合中
var beacon = value;
Set(value);
value.OnPropertyChanged += (s,e) => { OnPropertyChanged(nameof(Beacon)); }这意味着,每次信标中的任何属性发生更改时,它都会说信标类本身发生了更改,并触发VisualState的INPC。
注意:请确保事件在重置时处于打开状态。这意味着不是像我上面展示的那样在无名函数中执行,而是执行+=并使用Tab键创建另一个方法。
发布于 2017-08-21 19:07:43
感谢Adam的帮助。这就是我最后所做的,也许它可以帮助其他人。
public class BeaconAddVisualState : BaseVisualState
{
private readonly IBeaconAddModel r_Model;
private Beacon m_Beacon;
public BeaconAddVisualState(IBeaconAddModel i_Model)
: base(i_Model)
{
r_Model = i_Model;
}
[Binding(BindingType.TwoWay)]
public Beacon Beacon
{
get
{
return m_Beacon;
}
set
{
if(m_Beacon != value)
{
if(m_Beacon != null)
{
m_Beacon.PropertyChanged -= m_Beacon_PropertyChanged;
}
m_Beacon = value;
m_Beacon.PropertyChanged += m_Beacon_PropertyChanged;
OnPropertyChanged();
}
}
}
public override async void Init()
{
Beacon = new Beacon();
}
public override void Disposing()
{
if (m_Beacon != null)
{
m_Beacon.PropertyChanged -= m_Beacon_PropertyChanged;
}
base.Disposing();
}
private void m_Beacon_PropertyChanged(
object i_Sender,
System.ComponentModel.PropertyChangedEventArgs i_EventArgs)
{
OnPropertyChanged(nameof(Beacon));
}
}https://stackoverflow.com/questions/45787386
复制相似问题