我有一个复选框,它应该触发按钮的IsEnabled事件。但不知何故,应该这样做的命令永远不会被正确绑定并因此被执行。
这是CheckBox.xaml.cs(控件)中的可绑定属性:
// PART DEFINITION
ContentDefinitionManager.AlterPartDefinition("ProductPart", p => p
.WithDescription("Product part")
// To select other contents ( on this example "ProductPresentation" content type )
.WithField("ProductPresentation", f => f
.OfType("ContentPickerField")
.WithDisplayName("Product presentation")
.WithSetting("ContentPickerFieldSettings.Required", "True")
.WithSetting("ContentPickerFieldSettings.Multiple", "True")
.WithSetting("ContentPickerFieldSettings.ShowContentTab", "True")
.WithSetting("ContentPickerFieldSettings.Hint", "Please select product's presentation")
.WithSetting("ContentPickerFieldSettings.DisplayedContentTypes", "ProductPresentation")
)
// To select images
.WithField("ProductImageField", f => f
.OfType("MediaLibraryPickerField")
.WithDisplayName("Product image")
.WithSetting("MediaLibraryPickerFieldSettings.Hint", "Please select product's image")
.WithSetting("MediaLibraryPickerFieldSettings.Required", "True")
.WithSetting("MediaLibraryPickerFieldSettings.Multiple", "False")
)
// To add a taxonomy field called "ProductLines"
.WithField("Category", fcfg => fcfg
.OfType("TaxonomyField")
.WithDisplayName("Category")
.WithSetting("TaxonomyFieldSettings.Taxonomy", "ProductLines")
.WithSetting("TaxonomyFieldSettings.LeavesOnly", "True")
.WithSetting("TaxonomyFieldSettings.Required", "True")
.WithSetting("TaxonomyFieldSettings.SingleChoice", "False")
.WithSetting("TaxonomyFieldSettings.Autocomplete", "False")
.WithSetting("TaxonomyFieldSettings.AllowCustomTerms", "False")
.WithSetting("TaxonomyFieldSettings.Hint", "Please select product's category")
)
.Attachable()
);
// CONTENT TYPE DEFINITION
ContentDefinitionManager.AlterTypeDefinition("Product", cfg => cfg
.DisplayedAs("Product")
.WithPart(
"CommonPart", c => c
.WithSetting("DateEditorSettings.ShowDateEditor", "False")
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "False")
)
.WithPart("ProductPart")
.WithPart("TitlePart", c => c.WithSetting("Hint", "Please enter the product name"))
.WithPart("BodyPart", c => c.WithSetting("Hint", "Please enter the product description"))
.WithPart("LocalizationPart")
.WithPart("AutoroutePart", partBuilder => partBuilder
.WithSetting("AutorouteSettings.AllowCustomPattern", "true")
.WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
.WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Product Title', Pattern: 'product/{Content.Slug}', Description: 'product/title-product'}]"))
.Listable()
.Draftable()
.Creatable()
.Securable()
.Indexed()
);
这就是我在ViewModel上的内容:
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); }
}
CheckBoxTapped方法永远不会被执行,因此我想要设置的按钮属性永远不会改变。
先谢谢大家!
答案 0 :(得分:2)
您可以做的是将此问题的解决方案分为几个级别:
首先,为复选框创建一个可绑定属性,并将其命名为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); }
}
其次,在视图模型中创建一个具有更改通知的bool属性
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中要做的就是将按钮的命令绑定到View Model中的命令(让我们称之为ClickCommand)。 ClickCommand的CanExecute实际上只是一个返回“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>
答案 1 :(得分:1)
使用Xamarin.Forms.Behavior解决它。它允许多个绑定到控件。
例如&gt;
<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&gt;
上public PasswordInputViewModel()
{
entry_Finished = new Command(validateAndContinue);//unfocused
entry_Focused = new Command(entryFocused); //focused
}