[英]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.