我创建了一个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很有意思。这是两个具有相同问题的独立代码库。 :/
答案 0 :(得分:0)
简单的答案;我绑定到基于另一个属性的模型中的只读属性。当其他属性更改时,我没有为只读属性触发OnPropertyChanged。