英文:
Unable to disable a button which has IsEnabled bound to a property
问题
我有一个问题,我似乎无法禁用一个与属性绑定了IsEnabled的按钮。
我有以下的XAML:
<Button Text="跳过" IsEnabled="{Binding SkipEnabled}" ... />
它被绑定到这个BindableProperty:
public static readonly BindableProperty SkipEnabledProperty = BindableProperty.Create(
propertyName: nameof(SkipEnabled), returnType: typeof(bool?), declaringType: typeof(WizardMasterPage), propertyChanged: SetSkipEnabled,
defaultValue: null, defaultBindingMode: BindingMode.TwoWay);
public bool? SkipEnabled
{
get { return (bool?)GetValue(SkipEnabledProperty); }
set { SetValue(SkipEnabledProperty, value); }
}
问题是按钮始终是可用的。
propertyChanged事件在属性设置为false的页面上没有触发 - 可能是因为在页面创建时它为false,所以它认为它没有改变,因此绑定没有更新。我注意到它在将属性设置为True的页面上触发了。
有其他人遇到过这个问题吗?有没有解决方法?
注意:我也尝试了使用bool,但那也不起作用。
谢谢
英文:
I have a problem where I can't seem to disable a button which has IsEnabled bound to a property.
I have the following XAML:
<Button Text="Skip" IsEnabled="{Binding SkipEnabled}" ... />
It is being bound to this BindableProperty:
public static readonly BindableProperty SkipEnabledProperty = BindableProperty.Create(
propertyName: nameof(SkipEnabled), returnType: typeof(bool?), declaringType: typeof(WizardMasterPage), propertyChanged: SetSkipEnabled,
defaultValue: null, defaultBindingMode: BindingMode.TwoWay);
public bool? SkipEnabled
{
get { return (bool?)GetValue(SkipEnabledProperty); }
set { SetValue(SkipEnabledProperty, value); }
}
The problem is the button is always enabled.
The propertyChanged event isn't firing on the pages where the property is set to false - presumably because it is false when the page is created, so doesn't think it has changed and hence the binding is not updated. I notice that it does fire on the pages where I set the property to True.
Has anyone else seen this? Are there any workarounds?
Note: I tried just bool as well and that didn't work either.
Thanks
答案1
得分: 0
以下是代码的翻译部分:
"Is this Button
included in a ContentView
, right?"(这个按钮是包含在一个ContentView
中的吗?)
"If yes, then you can refer to the following code."(如果是的话,那么你可以参考以下的代码。)
"I achieved this function and I added a Button on the current page to reset the value, then the UI could refresh automatically."(我实现了这个功能,并在当前页面上添加了一个按钮来重置数值,然后界面可以自动刷新。)
"ChildView.xaml.cs"(ChildView.xaml.cs)
"ChildView.xaml"(ChildView.xaml)
"MainPage.xaml"(MainPage.xaml)
"MyViewModel.cs"(MyViewModel.cs)
英文:
Is this Button
included in a ContentView
, right?
If yes, then you can refer to the following code.
I achieved this function and I added a Button on the current page to reset the value, then the UI could refresh automatically.
ChildView.xaml.cs
public partial class ChildView : ContentView
{
public String YourName
{
get
{
String value = (String)GetValue(YourNameProperty);
return value;
}
set
{
SetValue(YourNameProperty, value);
}
}
public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
, typeof(String)
, typeof(ChildView), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);
public bool SkipEnabled
{
get
{
bool value = (bool)GetValue(SkipEnabledProperty);
return value;
}
set
{
SetValue(YourNameProperty, value);
}
}
public static readonly BindableProperty SkipEnabledProperty = BindableProperty.Create(nameof(SkipEnabled)
, typeof(bool)
, typeof(ChildView), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);
static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
{
Console.WriteLine("-----------------> " + newValue);
}
public ChildView()
{
InitializeComponent();
}
}
ChildView.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiContentViewApp.ChildView"
x:Name="TestControlView"
>
<VerticalStackLayout>
<Label Text="{Binding Source={x:Reference TestControlView}, Path=YourName}"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Button Text="Skip" IsEnabled="{Binding Source={x:Reference TestControlView}, Path=SkipEnabled}" />
</VerticalStackLayout>
</ContentView>
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mauiapp="clr-namespace:MauiContentViewApp"
x:Class="MauiContentViewApp.MainPage">
<ContentPage.BindingContext>
<mauiapp:MyViewModel></mauiapp:MyViewModel>
</ContentPage.BindingContext>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<mauiapp:ChildView YourName="{Binding TestName}" SkipEnabled="{Binding TestBoolvalue}" ></mauiapp:ChildView>
<Button Text="reset" Command="{Binding ResetValueCommand}"/>
</VerticalStackLayout>
</ContentPage>
MyViewModel.cs
public class MyViewModel: INotifyPropertyChanged
{
private string _testName;
public string TestName
{
set { SetProperty(ref _testName, value); }
get { return _testName; }
}
private bool _testBoolValue;
public bool TestBoolvalue
{
set { SetProperty(ref _testBoolValue, value); }
get { return _testBoolValue; }
}
public ICommand ResetValueCommand => new Command(resetMethod);
private void resetMethod(object obj)
{
TestName = "reset test string";
TestBoolvalue = !TestBoolvalue;
}
public MyViewModel()
{
TestName = "test string";
TestBoolvalue = false;
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论