簡體   English   中英

Xamarin.Forms中的XAML綁定問題

[英]XAML Binding issues in Xamarin.Forms

我創建了一個可以在我的整個項目中重復使用的ViewCell:

<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:C="using:****.Converters"
         x:Class="****.Views.Settings.SettingCell">
<Grid BackgroundColor="{StaticResource BlueGray}">
    <Grid.Resources>
        <C:DebugConverter x:Key="debugConverter"/>
    </Grid.Resources>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Image Grid.Column="0" Source="{Binding ImageSource}"/>
    <Label Grid.Column="1" 
           Text="{Binding Path=Title,
                          Converter={StaticResource debugConverter}, 
                          FallbackValue=Title}" 
           HorizontalOptions="Start" 
           VerticalOptions="Center"/>
    </Grid>
</ViewCell>

這是ViewModel:

public partial class SettingCell : ViewCell
{
    public SettingModel Model
    {
        get
        {
            return model;
        }
        set
        {
            model = value;
            BindingContext = value;
        }
    }
    public SettingModel model;

    public static readonly BindableProperty SettingTypeProperty = BindableProperty.Create(nameof(SettingType), typeof(Setting), typeof(SettingModel));
    public Setting SettingType
    {
        get
        {
            return (Setting)GetValue(SettingTypeProperty);
        }
        set
        {
            SetValue(SettingTypeProperty, value);
        }
    }

    public SettingCell()
    {
        InitializeComponent();

        switch (SettingType)
        {
            case Setting.Name:
                Model = new NameSettingModel();
                break;
            default:
                throw new NotImplementedException("Unknown Setting Type");
        }
    }
}

模型是通過類區分符選擇的抽象類的子類型。 這時該類非常簡單,因為我只是將其連接起來,但這是基類以及on子類型:

public class NameSettingModel : SettingModel
{
    public NameSettingModel()
    {
        Title = "Name";
        IconSource = "";
    }

    public override void ClickCommand()
    {
        Debug.WriteLine("Setting Command Run");
    }
}

public abstract class SettingModel : BindableBase
{
    public string Title
    {
        get
        {
            return GetProperty<string>();
        }
        set
        {
            SetProperty(value);
        }
    }
    public string IconSource
    {
        get
        {
            return GetProperty<string>();
        }
        set
        {
            SetProperty(value);
        }
    }

    public abstract void ClickCommand();
}

BindableBase只是實現INotifyPropertyChanged的基本綁定類,並將屬性值存儲在字典中,因此我不必為每個屬性都創建一個字段。

當我運行項目時; 每次都會顯示后備值。 讓我感到奇怪的是,當我在debugConverter中中斷時,如下所示:

public class DebugConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

我看到值“名稱”通過轉換器,但是UI僅顯示后備值。 有任何想法嗎? 綁定將獲得正確值但不刷新以顯示它的任何原因是什么? 我在這里茫然。 我很樂意發布更多可能有用的代碼,請給我留言。

謝謝!

===========================編輯==================== =======

情節變厚。 現在,我有一個直接位於列表視圖中的視單元,而我插入的模板只是一個網格。

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
  xmlns:Images="clr-namespace:MyApp.Images;assembly=MyApp"        
  xmlns:Converters="clr-namespace:MyApp.Views.Converters"
  x:Class="MyApp.Views.Templates.SettingTemplate" 
  BackgroundColor="White" VerticalOptions="Center">
<Grid.Resources>
     <Converters:SettingToIconConverter x:Key="SettingToIconConverter"/>
     <Converters:InverseBoolConverter x:Key="InverseBoolConverter"/>
</Grid.Resources>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="Center">
    <Images:VectorImage ResourceId="{Binding Converter={StaticResource SettingToIconConverter}}"
                        WidthRequest="30" HeightRequest="30" Margin="2"  VerticalOptions="Center"/>
    <Label Text="{Binding Name, FallbackValue=Name}" FontAttributes="Bold" FontSize="Medium" Margin="2" 
           VerticalOptions="Center"/>
    <ContentPresenter Content="{Binding BonusContent}" VerticalOptions="Center" Margin="2"/>
</StackLayout>
<Frame BackgroundColor="{StaticResource Slate}" Opacity="0.25" IsVisible="{Binding IsEnabled, UpdateSourceEventName=ValueChanged, Converter={StaticResource InverseBoolConverter}, FallbackValue=false}"/>

這是包含兩個模板的包含列表頁面:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="75"/>
            <RowDefinition Height="1"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Templates:PeripheralDetailsTemplate/>
        <Frame BackgroundColor="{StaticResource Slate}" Grid.Row="1"/>
        <Frame BackgroundColor="White" Grid.Row="2">
            <ListView x:Name="lvPeripheralSettings" ItemsSource="{Binding Settings}" 
                      SelectionMode="None" ItemTapped="Setting_Tapped" RowHeight="40"
                      ios:ListView.SeparatorStyle="FullWidth">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell IsEnabled="{Binding IsEnabled, UpdateSourceEventName=ValueChanged, Mode=TwoWay, Converter={StaticResource DebugConverter}}">
                            <Templates:SettingTemplate/>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Frame>
    </Grid>

注意PeripheralDetailsTemplate:

   <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="75"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="75"/>
    </Grid.ColumnDefinitions>
    <!--Icon--> 
    <Frame Padding="5">
         <Images:VectorImage ResourceId="{Binding HardwareType, Converter={StaticResource hardwareTypeToSVGPathConverter}}"
                             WidthRequest="150" HeightRequest="150" 
                             HorizontalOptions="Center" VerticalOptions="Center"/>
    </Frame>
    <Grid Grid.Column="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Frame>
            <Label Text="{Binding Name, FallbackValue=Peripheral Name}" FontSize="Medium" FontAttributes="Bold" HorizontalOptions="Start" VerticalOptions="Center"/>
        </Frame>
        <Frame Grid.Row="1">
            <Label Text="{Binding HardwareType, FallbackValue=Peripheral Type}" FontSize="Micro" HorizontalOptions="Start" VerticalOptions="Center"/>
        </Frame>
        <Frame Grid.Row="2">
            <Label Text="{Binding MacAddress, StringFormat='Mac: {0}', FallbackValue=000111222333}" FontSize="Micro" HorizontalOptions="Start" VerticalOptions="Center"/>
        </Frame>
        <Frame Grid.Row="3">
            <Label Text="{Binding FirmwareRevision, StringFormat='Firmware: {0}', FallbackValue=01AB}" FontSize="Micro" HorizontalOptions="Start" VerticalOptions="Center"/>
        </Frame>
    </Grid>
    <Frame Grid.Column="2">
        <Label Text="Conn" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{Binding IsConnected, Converter={StaticResource BoolToColorConverter}, FallbackValue={StaticResource LynkdBlue}}"/>
    </Frame>
</Grid>

它必然與ViewCell完全一樣!!! 而且效果很好。 我正在尋找差異,但尚未找到。 我只知道我已經正確設置了綁定上下文,因為它一次綁定了數據,而且我知道我正在正確觸發NotifyPropertyChanged,因為綁定到相同屬性的另一個模板會按我的期望進行更新。 我已經連接了一個debugconverter,它永遠不會運行。 我認為在兩種情況下都使用ViewCell很有意思。 這是兩個具有相同問題的獨立代碼庫。 :/

簡單的答案; 我綁定到基於另一個屬性的模型中的只讀屬性。 當其他屬性更改時,我沒有為只讀屬性觸發OnPropertyChanged。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM