【问题标题】:Xamarin Forms Binding layout with DataTemplateSelectorXamarin 表单绑定布局与 DataTemplateSelector
【发布时间】:2020-02-29 23:45:19
【问题描述】:

我的代码有效,但在我看来,它是一个笨拙的剪切和粘贴解决方案。我正在寻找一种更有效的 XAML 编码方式,这样 Grid 就不需要定义两次,而是使用不同的背景颜色

代码为 ListView 的行生成交替颜色背景。这是与Alternate row color ListView xamarin forms 不同的问题。

我的代码的简化示例:

<ContentPage.Resources>
    <DataTemplate x:Key="evenTemplate">
        <ViewCell>
            <Grid BackgroundColor="White" >
            <Label Text="{Binding Data}" />
            </Grid>
        </ViewCell>
    </DataTemplate>
    <DataTemplate x:Key="unevenTemplate">
        <ViewCell>
            <Grid BackgroundColor="Black" >
            <Label Text="{Binding Data}" />
            </Grid>
        </ViewCell>
    </DataTemplate>
    <local:AlternateColorDataTemplateSelector x:Key="alternateColorDataTemplateSelector"
            EvenTemplate="{StaticResource evenTemplate}"
            UnevenTemplate="{StaticResource unevenTemplate}" />
</ContentPage.Resources>
<ContentPage.Content>
    <ListView ItemTemplate="{StaticResource alternateColorDataTemplateSelector}" />
</ContentPage.Content>

实际的代码比这复杂得多。问题是使用这种设计,我有两个相同的网格副本,唯一的区别是背景。实际代码最终重复了大约 23 行 XAML,这导致了可维护性的噩梦——当需要更改一件事时,我必须在两个地方进行更改(如标签所示)。

我尝试在 DataTemplate 之外定义 Grid 并将其绑定到 ContentView 的内容,但是网格内的控件没有绑定到我的模型(ContentPage 的 BindingContext)。换句话说,标签不再绑定到数据。示例如下:

<Grid x:Key="mainGrid" >
    <Label Text="{Binding Data}" />
</Grid>
<DataTemplate x:Key="evenTemplate">
    <ViewCell>
        <ContentView Content={StaticResource mainGrid}" BackgroundColor="White" />
    </ViewCell>
</DataTemplate>
<DataTemplate x:Key="evenTemplate">
    <ViewCell>
        <ContentView Content={StaticResource mainGrid}" BackgroundColor="Black" />
    </ViewCell>
</DataTemplate>

所以,问题就变成了,我该怎么做,这样 Grid 只需要定义一次,但绑定正确并且我有交替的行颜色?

【问题讨论】:

  • @Nirmal Subedi 不是重复的。看两个帖子。一方面,我试图专门在 XAML 中执行此操作。另一方面,它涵盖了创建一个 DatatemplateSelector,我的代码已经这样做了。我的问题是创建一个更有效的解决方案。
  • 如果您有 2 个基于奇数/偶数行的不同视图,那么为它们创建 DataTemplate 更有意义,但只是为了制作“仅备用背景颜色”,我不建议使用 2不同的数据模板!
  • @Nirmal Subedi。你没有帮助 - 完全重读我的帖子。你的建议正是我要问的,我讨论了我遇到的问题。我想这可能是我缺少的一件简单的事情。
  • 我误解了您的问题,因此,您可以在同一页面 XAML 中定义您的 Grid,而是将其创建为一个新对象,然后在任何您想要的地方引用它。请参阅以下答案并根据需要进行更正。如果您需要更多帮助,请告诉我

标签: xamarin.forms


【解决方案1】:

很抱歉,我误解了您的问题。因此,您希望在多个位置的视图单元中重用网格代码。为此,我将创建一个新的 Xaml 文件并将该网格的所有内容放在那里,例如:

<Grid ... ... x:Class="TestProject.TestGrid">
   <Label Text="{Binding Name}"/>
</Grid>

然后在我的 DataTemplate 中:

<DataTemplate x:Key="evenTemplate">
<ViewCell>
    <ContentView BackgroundColor="White">
        <local:TestGrid />
    </ContentView>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="evenTemplate">
<ViewCell>
    <ContentView BackgroundColor="Black">
        <local:TestGrid />
    </ContentView>
</ViewCell>
</DataTemplate>

我没有在我的 Visual Studio 上尝试过这个,我只是在打字。您可能需要进行更正。

【讨论】:

  • 这行得通。谢谢。它确实解决了这个问题。代码可以进一步简化——不需要包裹在 TestGrid 周围的
  • 很高兴它成功了。是的,你可以让它以最好的方式工作;这只是一个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 2018-01-25
  • 1970-01-01
  • 2018-07-06
  • 2016-10-10
  • 2018-12-16
相关资源
最近更新 更多