无法禁用一个具有与属性绑定的IsEnabled的按钮

huangapple go评论69阅读模式
英文:

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;
}

huangapple
  • 本文由 发表于 2023年2月19日 18:04:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定