4

How can I change GridViewItems visibility using property binding?

I can't create another ObservableCollection to filter the one I am using as ItemsSource. I tried to use GridView.ItemContainerStyle to change the GridViewItem style but it seems that it does not work with binding (although it works if I set the value to Collapsed).

<GridView.ItemContainerStyle>
    <Style TargetType="GridViewItem">
        <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource booleanToVisibilityConverter}}" />
    </Style>
</GridView.ItemContainerStyle>

I also tried to use a DataTemplateSelector. I can hide items with binding but then there are gaps on my GridView because the ItemContainer is still there and does not collapse.

I need the GridView items to be collapsed and not just hidden.

EDIT: Why do I want to get rid of filtered ObservableCollections?

I am trying to mirror 2 GridViews and 1 ListView with the same ItemsSource and SelectedItem both binded with my ViewModel properties Items and Current. Without filters it works as I expect without SelectionChanged events, but with only Two-Way Binding.

But those GridView/Listview must have some differences such as the available items for selection and its DataTemplates. So I am using filtered collections that brought me problems.

For example:

  • GridView1 has Items 1, 2 and 3
  • GridView2 has only Items 1 and 3
  • I select Item 1 of GridView1
  • I select Item 2 of GridView1

When I select Item 1 it also gets selected on GridView2. Good for now. When I select Item 2, Item 1 maintains selected on GridView2. GridView2 should now be without selection but if I force it to it will always deselect Item 2 of GridView2 since SelectedItem of both is Two-Way binded.

I hope this is understandable because English is not my native language.

4

2 回答 2

1

因此,首先,该样式不起作用,因为 WinRT 显然不支持 setter 中的绑定(请参阅此处)。本文确实提到了解决此问题的方法,希望它对您有用(尽管我自己没有尝试过)。

如果不成功,GridView 最终只是一个 ItemsControl,因此您应该能够通过将其 ItemsPanel 属性设置为自定义面板来手动覆盖布局。您可以制作一个像这样的小型自定义面板,与用于折叠 GridViewItems 内容的 DataTemplateSelector 结合使用:

class CustomPanel : Panel
{
    //Children of this panel should be of type GridViewItem (which is the ItemContainer for the
    //ItemsControl)

    protected override Size MeasureOverride(Size availableSize)
    {
        foreach (var child in this.Children)
        {
            var interior = (UIElement)VisualTreeHelper.GetChild(child, 0);
            interior.Measure(availableSize);

            if (interior.DesiredSize.Width == 0 && interior.DesiredSize.Height == 0)
                //Skip this item
            else
            {
                child.Measure(availableSize);
                //Update the total measure of the panel with child.DesiredSize...
            }

            //Return the total calculated size
        }
    }

    protected Size override ArrangeOverride(Size finalSize)
    {
        foreach (var child in this.Children)
        {
            var interior = (UIElement)VisualTreeHelper.GetVisualChild(child, 0);

            if (interior.DesiredSize.Width == 0 || interior.DesiredSize.Height == 0)
                //Skip this item
            else
                //Call child.Arrange with the appropriate arguments and update the total size
                //used...

            //Return the total size used
        }
    }
}

这段代码可以稍微清理一下,但这样的事情应该能够解决处理出现的空 GridViewItems 的问题。

于 2014-02-09T21:43:22.743 回答
-1

您可以使用项目索引从后面的代码中修改 GridViewItem 可见性。项目索引与您在 ObservableCollection 中的索引相同

var gridViewItem = (GridViewItem)this.GridView.ContainerFromIndex(index);
gridViewItem.Visibility = Visibility.Visible;
于 2015-08-08T20:02:38.587 回答