【问题标题】:XAML Binding issues in Xamarin.FormsXamarin.Forms 中的 XAML 绑定问题
【发布时间】:2018-10-15 20:16:21
【问题描述】:

我创建了一个可以在整个项目中重复使用的 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");
        }
    }
}

模型是通过类鉴别器选择的抽象类的子类型。这个类在这一点上非常简单,因为我只是把它连接起来,但这里是基类和子类型:

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 具有完全相同的属性!!!它工作正常。我正在寻找不同之处,但还没有找到。我只知道我已经正确设置了 bindingcontext,因为它数据绑定了一次,并且我知道我正确地触发了 NotifyPropertyChanged,因为绑定到相同属性的另一个模板会按照我的预期进行更新。我附加了一个调试转换器,它永远不会运行。我认为有趣的是,在这两种情况下,我都在使用 ViewCell。这是两个具有相同问题的独立代码库。 :/

【问题讨论】:

  • 在您的转换器中,您是否尝试过返回字符串而不是对象?
  • 值得一试,我这几天都回不去了,但我会再试一次。
  • 好吧,由于一次愚蠢的 Git 事故,我失去了所有的工作,我已经重做了所有的工作,现在一切正常......我不知道我做了什么不同
  • 而且,我又回到了这个问题

标签: c# xaml xamarin xamarin.forms


【解决方案1】:

简单的答案;我正在绑定到我的模型中基于另一个属性的只读属性。当另一个属性更改时,我没有为只读属性触发 OnPropertyChanged。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 2020-10-19
    • 2020-09-12
    • 2014-11-12
    • 2018-02-17
    相关资源
    最近更新 更多