【问题标题】:PrepareContainerForItemOverride works different in Desktop than in Mobile UWPPrepareContainerForItemOverride 在桌面与移动 UWP 中的工作方式不同
【发布时间】:2016-07-27 02:41:30
【问题描述】:

我想根据数据值改变 ListView 的一项颜色。 这样做很容易:

 <ListView.ItemContainerStyle>
         <Style TargetType = "ListViewItem" >
         < Setter Property="Background" Value="{Binding EventType, Converter={StaticResource EventTypeToBackColorConverter}}"  />
 </ListView.ItemContainerStyle>

但问题是 UWP 不支持在 Setter Properties 中进行绑定。 我的第二次尝试是覆盖 ListView 的 PrepareContainerForItemOverride:

public class EventListView : ListView
{
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        base.PrepareContainerForItemOverride(element, item);
        var listViewItem = element as ListViewItem;
        var ev = item as EventType;
        if(ev.Warning)
           listViewItem.Background = new SolidColorBrush(Color.Red);
    }
}

以上代码在装有 Windows 10 和 UWP 的 PC 上运行良好。它根据基础数据将某些项目涂成红色。当我在 Windows Mobile 中运行相同的应用程序时,一开始它运行良好,但是当我向上滚动然后向下滚动时,返回到开始时可以正常显示的原始视图,现在其他项目也为红色。

我错过了什么?

【问题讨论】:

    标签: xaml windows-10 uwp


    【解决方案1】:

    我不确定原因,但以下代码对我有用:

    public class EventListView : ListView
    {
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            var listViewItem = element as ListViewItem;
            var ev = item as EventType;
            if(ev.Warning)
               listViewItem.Background = new SolidColorBrush(Color.Red);
            else
               listViewItem.Background = null;
        }
    }
    

    我已添加listViewItem.Background = null

    【讨论】:

      【解决方案2】:

      这是因为当Item数量较多时,默认ListView已经实现了数据虚拟化的功能。禁用此功能不是一个好主意,因为它可以获得更好的性能。

      但是对于您的情况,有一种更简单的方法可以解决您的问题。由于您在后面的代码中试图修改ListViewItem的样式,而我们无法修改现有的样式,我们可以将ListViewItem的新样式设置为ListView,例如这样:

      private void Button_Click(object sender, RoutedEventArgs e)
      {
          var dynamicStyle = new Style();
          dynamicStyle.TargetType = typeof(ListViewItem);
          dynamicStyle.Setters.Add(new Setter(BackgroundProperty, Colors.Red));
          listView.ItemContainerStyle = dynamicStyle;
      }
      

      只有一个问题是,如果您将Background 属性设置为所有ListViewItem,这与将数据绑定到ListViewBackground 属性或将Background 设置为@987654331 没有区别@像这样:

      listView.Background = new SolidColorBrush(Colors.Red);
      

      所以我只是假设您想修改DataTemplate 中的根控件,例如以下xaml 中的Grid

      <ListView x:Name="listView" ItemsSource="{x:Bind collection}">
          <ListView.ItemContainerStyle>
              <Style TargetType="ListViewItem" x:Name="myListItemStyle">
                  <Setter Property="HorizontalContentAlignment" Value="Stretch" />
              </Style>
          </ListView.ItemContainerStyle>
          <ListView.ItemTemplate>
              <DataTemplate>
                  <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                      <TextBlock Text="{Binding Testtext}" />
                  </Grid>
              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
      

      那么在这种情况下,你可以像这样使用数据绑定:

      <DataTemplate>
          <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{Binding EventType, Converter={StaticResource EventTypeToBackColorConverter}}">
              <TextBlock Text="{Binding Testtext}" />
          </Grid>
      </DataTemplate>
      

      无论如何,如果你坚持要更改ListView中所有ListViewItem的某些属性,可以使用我提供的第一种方法。

      【讨论】:

      • 感谢您的回复。问题是每个项目都可以有不同的颜色,所以 ListView.Background 不是一个解决方案。使用 DataTemplate 的第二个选项对我不起作用,因为颜色不会像选择一样填充整个矩形。有边距。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多