【问题标题】:Change GridView Items size更改 GridView 项目大小
【发布时间】:2019-02-23 00:10:28
【问题描述】:

我要实现两个功能:

  1. 将 GridView 更改为 Listview。

  2. 用户可以更改项目大小。

两者我都实现了,但是组合起来有问题

在 xaml 中,我有两个 ItemsPanelTemplate:

<!--Two mode-->
    <ItemsPanelTemplate x:Key="ItemsStackPanelTemplate">
        <ItemsStackPanel />
    </ItemsPanelTemplate>

    <ItemsPanelTemplate x:Key="ItemsWrapGridTemplate">
        <ItemsWrapGrid Orientation="Horizontal"/>
    </ItemsPanelTemplate>

在代码中,我有一个更改视图的按钮:

if(Viewstatus == "GridView")
{
    //now it is gridview, then change to listview
    girdView.ItemsPanel = this.Resources["ItemsStackPanelTemplate"] as ItemsPanelTemplate;
    girdView.ItemTemplate = this.Resources["listviewdata"] as DataTemplate;
    Viewstatus = "ListView";
}
else
{
    girdView.ItemsPanel = this.Resources["ItemsWrapGridTemplate"] as ItemsPanelTemplate;
    girdView.ItemTemplate = this.Resources["BookDataTemplate"] as DataTemplate;
    Viewstatus = "GridView";
}

而且我有一个改变大小的函数代码(myTitle 是一个保存一些状态的对象):

ItemsWrapGrid appItemsPanel = (ItemsWrapGrid)girdView.ItemsPanelRoot;
if(myTitle != null)
{
    appItemsPanel.ItemWidth = myTitle.ZoomValue;
    appItemsPanel.ItemHeight = myTitle.ZoomValue + 20;
    zoom = myTitle.ZoomValue;
}

两个都是正常的,但是当我换了views的时候就不能改变size了;

因为当我更改了 GridView 的 ItemsPanel 时,我的 GridView 的 ItemsPanelRoot 为空。

所以我无法获得girdView.ItemsPanelRoot

我该怎么做?我怎样才能同时拥有这两个功能?我的方法不对?

更新:感谢标记的答案。

但我有一个新问题:

在 changeView 方法中我的代码有问题:

if(Viewstatus == "GridView")
{
    //now it is gridview, then change to listview
    girdView.ItemsPanel = this.Resources["ItemsStackPanelTemplate"] as ItemsPanelTemplate;
    girdView.ItemTemplate = this.Resources["listviewdata"] as DataTemplate;
    IEnumerable<Grid> items = VisualTreeHelperClass.FindVisualChildren<Grid>(girdView);
    foreach (var item in itemsa)
    {
        if(item.Name == "myGrid")
            item.Width = myTitle.Framesize;
    }
    Viewstatus = "ListView";
}
else
{
    girdView.ItemsPanel = this.Resources["ItemsWrapGridTemplate"] as ItemsPanelTemplate;
    girdView.ItemTemplate = this.Resources["BookDataTemplate"] as DataTemplate;
    Viewstatus = "GridView";
}

我失败了。(myGrid 是模板中的网格名称,如果我不这样做,它将改变视图的所有宽度。我尝试删除 if(item.Name == "myGrid"),它会改变一些其他视图的宽度,我在 Debug.WriteLine 中看到了)

但是我有另一种方法,我调用该方法来运行相同的代码,它可以工作。

所以我认为

如果我更改视图并立即找到视图的子视图(两种方法合二为一),我将失败。

如果我改变视图,我会做一些事情来调用另一个方法,它会起作用。

我尝试使用:

public void ChangeView(){
    //code that change view
    .........
    ChangeSize();
}
public void ChangeSize(){
    //find child and change size code
}

也不行。

我想,如果我想改变尺寸,改变尺寸代码必须与 更改视图代码。

【问题讨论】:

    标签: c# gridview uwp


    【解决方案1】:

    因为当我更改了 GridView 的 ItemsPanel 时,我的 GridView 的 ItemsPanelRoot 为空。

    如果您更改了GridViewItemsPanel,则ItemsPanel 将变为ItemsStackPanel 对象,而不是ItemsWrapGrid 对象。这样你就不能得到一个ItemsWrapGrid 对象,但是GridView 的ItemsPanelRoot 不是空的,它是一个ItemsStackPanel

    ItemsStackPanel appItemsPanel = (ItemsStackPanel)girdView.ItemsPanelRoot;
    

    更改 GridVew 项目的大小

    但是ItemsStackPanel 没有ItemsWrapGrid 具有的直接设置项目高度和宽度的属性。实际上,无论当前设置哪个ItemsPanel,您始终可以使用VisualTreeHelper 获取GridViewItems 并设置高度和宽度属性。例如:

    private void btnchangesize_Click(object sender, RoutedEventArgs e)
    {
        IEnumerable<GridViewItem> items = FindVisualChildren<GridViewItem>(girdView);
        foreach (var item in items)
        {
            item.Height = 80;
            item.Width = 100;
        }  
    }
    private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }
    
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,我的意思是,如果APP启动时GridVIew.ItemsPanel ItemsWrapGrid,现在我可以得到ItemsPanelRoot对象。然后我切换到List模式,如你所说, ItemsPanel 将是 ItemsStackPanel,但现在 ItemsPanelRoot 已经为空。我通过 VS 的调试看到了这一点(我可能错了)。然后我改回来,ItemsPanel ItemsWrapGrid,@ 987654345@ 也是空的,不知道为什么
    • 我已经解决了,你是对的,有一些例外情况
    • 对不起,我还有一个问题:当我在一个方法中更改了GridVIew.ItemsPanel,然后我尝试获取ItemsPanelRoot(代码在这个方法中),它是空的。我得到@987654350 @在其他方法中,这是正常的......我使用你的代码来查找项目,它失败了(代码也在那个方法中)。但是我用你的代码用其他方法找到它们是正常的。为什么,?我不知道如何解决它。谢谢
    • @haihanjin,那这个特殊的方法是什么?您能否详细说明该方法与其他常规方法的区别?
    • 我已经更新了我的问题,我在里面写下了我的状态,非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多