การผูกคุณสมบัติตามแพลตฟอร์มใน XAML ล้มเหลว

ฉันเขียนโค้ด XAML และ C# ด้านล่างเพื่อตั้งค่าคุณสมบัติ IsVisible ของ ActivityIndicator ถึง True บน Android และ iOS รหัส C# ในโค้ดด้านหลังผูกคุณสมบัติเดียวกันกับคุณสมบัติ IsBusy ของบริบทการผูกบน Windows รหัสนี้ใช้งานได้ตามที่คาดไว้บนทุกแพลตฟอร์ม

# XAML Code
<ActivityIndicator x:Name="AI" IsEnabled="{Binding Path=IsBusy}" IsVisible="True"  IsRunning="{Binding Path=IsBusy}"/>

# C# Code
if (Device.RuntimePlatform == Device.Windows)
{
    AI.SetBinding(IsVisibleProperty, new Binding(nameof(ViewModel.IsBusy)));
}

ฉันต้องการให้มีพฤติกรรมเดียวกันโดยใช้ XAML เท่านั้น ฉันลองใช้ข้อมูลโค้ดด้านล่างซึ่งไม่ได้ผลเลย

# 1
# Compiles. On Windows throws System.InvalidCastException: 
# 'Unable to cast object of type 'Xamarin.Forms.Binding' 
# to type 'System.Boolean'.'
<ActivityIndicator x:Name="AI" IsEnabled="{Binding Path=IsBusy}" IsRunning="{Binding Path=IsBusy}">
    <ActivityIndicator.IsVisible>
        <OnPlatform x:TypeArguments="x:Boolean">
            <On Platform="Android" Value="True"/>
            <On Platform="iOS" Value="True"/>
            <On Platform="Windows" Value="{Binding Path=IsBusy}"/>
        </OnPlatform>
    </ActivityIndicator.IsVisible>
</ActivityIndicator>

# 2
# Doesn't compile. Gives an error saying "No property, 
# bindable property, or event found for 'IsVisible'"
<ActivityIndicator x:Name="AI" IsEnabled="{Binding Path=IsBusy}" IsVisible="True" IsRunning="{Binding Path=IsBusy}">
    <ActivityIndicator.IsVisible>
        <OnPlatform x:TypeArguments="BindingBase">
            <On Platform="Windows" Value="{Binding Path=IsBusy}"/>
        </OnPlatform>
    </ActivityIndicator.IsVisible>
</ActivityIndicator>

# 3
# Doesn't compile. Gives an error saying "No property, 
# bindable property, or event found for 'IsVisible'"
<ActivityIndicator x:Name="AI" IsEnabled="{Binding Path=IsBusy}" IsVisible="True" IsRunning="{Binding Path=IsBusy}">
    <ActivityIndicator.IsVisible>
        <OnPlatform x:TypeArguments="Binding">
            <On Platform="Windows" Value="{Binding Path=IsBusy}"/>
        </OnPlatform>
    </ActivityIndicator.IsVisible>
</ActivityIndicator>

# 4
# Compiles. On Windows throws System.InvalidCastException: 
# 'Unable to cast object of type 'Xamarin.Forms.Binding' 
# to type 'System.Boolean'.'
<ActivityIndicator x:Name="AI" IsEnabled="{Binding Path=IsBusy}" IsVisible="True" IsRunning="{Binding Path=IsBusy}">
    <ActivityIndicator.IsVisible>
        <OnPlatform x:TypeArguments="x:Boolean">
            <On Platform="Windows">
                <Binding Path="IsBusy" />
            </On>
        </OnPlatform>
    </ActivityIndicator.IsVisible>
</ActivityIndicator>

เป็นไปได้ไหมที่จะทำสิ่งนี้ใน XAML เลย?


person nlogn    schedule 12.09.2017    source แหล่งที่มา
comment
ฉันไม่คิดว่าคุณสามารถตั้งค่าทั้งแอตทริบิวต์ IsVisible และองค์ประกอบ ActivityIndicator.IsVisible ในเวลาเดียวกันได้   -  person Bradley Uffner    schedule 12.09.2017
comment
@BradleyUffner ดูเหมือนว่านั่นไม่ใช่ปัญหา ไม่มีตัวอย่าง XAML ข้างต้นใดที่ใช้งานได้โดยมีหรือไม่มีแอตทริบิวต์ IsVisible อยู่แล้ว   -  person nlogn    schedule 12.09.2017


คำตอบ (1)


ฉันไม่แน่ใจว่าเหตุใดตัวเลือก BindingBase จึงใช้งานไม่ได้ แต่สำหรับกรณีอื่นๆ เป็นที่ชัดเจนว่าปัญหาคือประเภทไม่ตรงกัน

เพื่อหลีกเลี่ยงปัญหาดังกล่าว ฉันเดาว่าคุณสามารถใช้ตัวตั้งค่าสไตล์เพื่อระบุค่าเริ่มต้นในขณะที่แทนที่โดยใช้ OnPlatform:

//App or Page resources to set default properties 
<ResourceDictionary>
    <Style TargetType="ActivityIndicator" x:Key="AIStyle">
        <Setter Property="IsEnabled" Value="{Binding Path=IsBusy}" />
        <Setter Property="IsRunning" Value="{Binding Path=IsBusy}" />
    </Style>
</ResourceDictionary>

//And use following to define control
<OnPlatform x:TypeArguments="View">
    <On Platform="Android, iOS">
        <ActivityIndicator IsVisible="true" Style="{StaticResource AIStyle}" />
    </On>
    <On Platform="Windows">
        <ActivityIndicator IsVisible="{Binding Path=IsBusy}" Style="{StaticResource AIStyle}" />
    </On>
</OnPlatform>
person Sharada Gururaj    schedule 13.09.2017