具有可绑定 属性 的自定义视图未在 Xamarin.Forms SAP 上正确绑定
Custom View with Bindable Property not binding properly on Xamarin.Forms SAP
我有一个复选框,它应该触发按钮的 IsEnabled 事件。但是不知何故,应该执行的命令永远不会被正确绑定并因此被执行。
这是 CheckBox.xaml.cs 中的可绑定 属性(控件):
public static readonly BindableProperty CheckBoxCommandProperty =
BindableProperty.Create<CheckBox, ICommand>(
checkbox =>
checkbox.CheckBoxCommand,
null,
propertyChanged: (bindable, oldValue, newValue) =>
{
CheckBox checkbox = (CheckBox)bindable;
EventHandler<bool> eventHandler = checkbox.CheckedChanged;
if (eventHandler != null)
{
eventHandler(checkbox, checkbox.IsChecked);
}
});
public event EventHandler<bool> CheckedChanged;
public ICommand CheckBoxCommand
{
get { return (ICommand)GetValue(CheckBoxCommandProperty); }
set { SetValue(CheckBoxCommandProperty, value); }
}
这就是我在 ViewModel 上的内容:
public ICommand Next_OnClick { get; set; }
public ICommand OnCheckBoxTapChanged { get; set; }
public TermsAndConditionsViewModel()
{
Next_OnClick = new Command(NextClicked);
OnCheckBoxTapChanged = new Command(CheckBoxTapped);
}
private void CheckBoxTapped()
{
if (IsCheckedChanged)
{
Next_IsEnabled = true;
}
else
{
Next_IsEnabled = false;
}
}
CheckBoxTapped 方法永远不会执行,因此我想设置的按钮 属性 永远不会改变。
在此先感谢大家!
你能做的就是把这道题的解法分成几个层次:
首先,为复选框创建一个可绑定的 属性 并将其命名为 Checked。
我已经为它写了一个 snippit 但没有真正编译它所以如果它不起作用你可能想修改它
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create<CheckBox, bool> (w => w.IsChecked, false);
public bool IsChecked{
get { return GetValue (FooProperty); }
set { SetValue (FooProperty, value); }
}
其次,在视图模型中创建一个具有更改通知的布尔值 属性
private bool _isChecked;
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
}
第三,将复选框 "isChecked" 的可绑定 属性 绑定到 xaml 中视图模型中的那个:
<StackLayout>
<Checkbox IsChecked = "{Binding IsChecked}"/>
</StackLayout>
第四,Xaml中的按钮与MVVM绑定到命令。在这些命令中有一个 bool 属性 代表 "CanExecute" ,它基本上启用或禁用按钮。所以你必须在 Xaml 中做的是将按钮的命令绑定到视图模型中的命令(我们称之为 ClickCommand)。而ClickCommand的CanExecute其实就是returns取"IsChecked"的方法。
这将使我们修改 "IsChecked" 属性 的 setter 所以每次它更改它应该通知命令检查 CanExecute 属性.
所以最终的代码会是这样的
public TermsAndConditionsViewModel()
{
NextCommand = new Command(ExecuteNextCommand,CanExecuteNextCommand);
OnCheckBoxTapChanged = new Command(CheckBoxTapped);
}
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked;}
set
{
_isChecked = value;
NextCommand.ChangeCanExecute(); //this will actually notify the command to enable/disable
RaisePropertyChanged("IsChecked");
}
}
public Command NextCommand {get;set;} // this type is available in Xamarin.Forms library
private bool CanExecuteNextCommand()
{
return IsChecked;
}
private void ExecuteNextCommand()
{
// your execution when the button is pressed
}
而 Xaml 会像
<StackLayout>
<Checkbox IsChecked = "{Binding IsChecked}"/>
<Button Text= "Next" Command = "{Binding NextCommand}"/>
</StackLayout>
使用 Xamarin.Forms.Behavior 解决了它。它允许对控件进行多个绑定。
例如>
<Entry Placeholder="Enter password"
Text= "{Binding TxtFirstPasswordInput}"
IsPassword="true">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand EventName="Unfocused" Command="{Binding entry_Finished}"/>
<b:EventToCommand EventName="Focused" Command="{Binding entry_Focused}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</Entry>
在 ViewModel 上>
public PasswordInputViewModel()
{
entry_Finished = new Command(validateAndContinue);//unfocused
entry_Focused = new Command(entryFocused); //focused
}
我有一个复选框,它应该触发按钮的 IsEnabled 事件。但是不知何故,应该执行的命令永远不会被正确绑定并因此被执行。
这是 CheckBox.xaml.cs 中的可绑定 属性(控件):
public static readonly BindableProperty CheckBoxCommandProperty =
BindableProperty.Create<CheckBox, ICommand>(
checkbox =>
checkbox.CheckBoxCommand,
null,
propertyChanged: (bindable, oldValue, newValue) =>
{
CheckBox checkbox = (CheckBox)bindable;
EventHandler<bool> eventHandler = checkbox.CheckedChanged;
if (eventHandler != null)
{
eventHandler(checkbox, checkbox.IsChecked);
}
});
public event EventHandler<bool> CheckedChanged;
public ICommand CheckBoxCommand
{
get { return (ICommand)GetValue(CheckBoxCommandProperty); }
set { SetValue(CheckBoxCommandProperty, value); }
}
这就是我在 ViewModel 上的内容:
public ICommand Next_OnClick { get; set; }
public ICommand OnCheckBoxTapChanged { get; set; }
public TermsAndConditionsViewModel()
{
Next_OnClick = new Command(NextClicked);
OnCheckBoxTapChanged = new Command(CheckBoxTapped);
}
private void CheckBoxTapped()
{
if (IsCheckedChanged)
{
Next_IsEnabled = true;
}
else
{
Next_IsEnabled = false;
}
}
CheckBoxTapped 方法永远不会执行,因此我想设置的按钮 属性 永远不会改变。
在此先感谢大家!
你能做的就是把这道题的解法分成几个层次:
首先,为复选框创建一个可绑定的 属性 并将其命名为 Checked。 我已经为它写了一个 snippit 但没有真正编译它所以如果它不起作用你可能想修改它
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create<CheckBox, bool> (w => w.IsChecked, false);
public bool IsChecked{
get { return GetValue (FooProperty); }
set { SetValue (FooProperty, value); }
}
其次,在视图模型中创建一个具有更改通知的布尔值 属性
private bool _isChecked;
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
}
第三,将复选框 "isChecked" 的可绑定 属性 绑定到 xaml 中视图模型中的那个:
<StackLayout>
<Checkbox IsChecked = "{Binding IsChecked}"/>
</StackLayout>
第四,Xaml中的按钮与MVVM绑定到命令。在这些命令中有一个 bool 属性 代表 "CanExecute" ,它基本上启用或禁用按钮。所以你必须在 Xaml 中做的是将按钮的命令绑定到视图模型中的命令(我们称之为 ClickCommand)。而ClickCommand的CanExecute其实就是returns取"IsChecked"的方法。 这将使我们修改 "IsChecked" 属性 的 setter 所以每次它更改它应该通知命令检查 CanExecute 属性.
所以最终的代码会是这样的
public TermsAndConditionsViewModel()
{
NextCommand = new Command(ExecuteNextCommand,CanExecuteNextCommand);
OnCheckBoxTapChanged = new Command(CheckBoxTapped);
}
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked;}
set
{
_isChecked = value;
NextCommand.ChangeCanExecute(); //this will actually notify the command to enable/disable
RaisePropertyChanged("IsChecked");
}
}
public Command NextCommand {get;set;} // this type is available in Xamarin.Forms library
private bool CanExecuteNextCommand()
{
return IsChecked;
}
private void ExecuteNextCommand()
{
// your execution when the button is pressed
}
而 Xaml 会像
<StackLayout>
<Checkbox IsChecked = "{Binding IsChecked}"/>
<Button Text= "Next" Command = "{Binding NextCommand}"/>
</StackLayout>
使用 Xamarin.Forms.Behavior 解决了它。它允许对控件进行多个绑定。
例如>
<Entry Placeholder="Enter password"
Text= "{Binding TxtFirstPasswordInput}"
IsPassword="true">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand EventName="Unfocused" Command="{Binding entry_Finished}"/>
<b:EventToCommand EventName="Focused" Command="{Binding entry_Focused}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</Entry>
在 ViewModel 上>
public PasswordInputViewModel()
{
entry_Finished = new Command(validateAndContinue);//unfocused
entry_Focused = new Command(entryFocused); //focused
}