在 WPF 中调整列表框项的大小

Resizing listbox items in WPF

我希望能够在 运行 中的程序中调整列表框中图像的大小和高度。

我的列表框如下:

<Grid>
    <ListBox x:Name="movieListBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="White">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel ItemHeight="300"
                           ItemWidth="200"
                           Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="5" HorizontalAlignment="Center">
                    <Image Margin="3" Source="{Binding path}" MouseDown="ImageClick_MouseDown" />
                    <TextBlock TextAlignment="Center" Text="{Binding name}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

如何在运行时更改列表框项目的高度和宽度? 例如按下按钮,每个项目的高度更改为“400”。

另外,如何返回列表框项目的当前大小?

更新

图像按以下方式加载到列表框中:

namespace Media_Console
{
    /// <summary>
    /// Interaction logic for MediaChooser.xaml
    /// </summary>
    public partial class MovieChooser : Page
    {
...
    private List<MovieListing> movie_posters_list = new List<MovieListing>();
...
    public void LoadImages(string foldername)
    {
        foreach (string folder in foldername)
        {
...
            movie_posters_list.Add(new MovieListing(imagelocation, filmName, quality, year));
        }

        movieListBox.ItemsSource = movie_posters_list;
        movieListBox.Items.Refresh();
    }
... 

    #region ChangeItemsSize

    public bool MakeItemsLarge
    {
        get { return _makeItemsLarge; }
        set
        {
            if (value != _makeItemsLarge)
            {
                _makeItemsLarge = value;
                Console.WriteLine("Edit to large");
                movieListBox.Items.Refresh();
                //LoadMovies(blankList, "ALL");
                OnPropertyChanged();
            }
        }
    }

    #endregion ChangeItemsSize


    public class MovieListing
    {
        public string name { get; set; }
        public string path { get; set; }
        public string quality { get; set; }
        public string year { get; set; }
        public string location { get; set; }

        public MovieListing(string path, string name, string quality, string year, string location)
        {
            this.path = path;
            this.name = name;
            this.quality = quality;
            this.year = year;
            this.location = location;
        }
    }
}

已更新XAML

<Grid>
    <ListBox x:Name="movieListBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="White" Margin="0,0,148,0">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
         </ListBox.ItemsPanel>
        <ListBox.ItemTemplate >
            <DataTemplate>
                <StackPanel x:Name="OuterPanel" Margin="5" HorizontalAlignment="Center">
                    <Image Margin="3" Source="{Binding path}" MouseDown="ImageClick_MouseDown" />
                    <TextBlock TextAlignment="Center" Text="{Binding name}"/>
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger 
                        Binding="{Binding DataContext.MakeItemsLarge, RelativeSource={RelativeSource AncestorType=ListBox}}"
                        Value="true"
                     >
                        <Setter
                            TargetName="OuterPanel"
                            Property="Height"
                            Value="350"
                            />
                        <Setter
                            TargetName="OuterPanel"
                            Property="Width"
                            Value="225"                                
                            />
                    </DataTrigger>
                    <DataTrigger 
                        Binding="{Binding DataContext.MakeItemsLarge, RelativeSource={RelativeSource AncestorType=ListBox}}"
                        Value="false"
                     >
                        <Setter
                            TargetName="OuterPanel"
                            Property="Height"
                            Value="315"
                            />
                        <Setter
                            TargetName="OuterPanel"
                            Property="Width"
                            Value="200"
                            />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

向您的主视图模型添加一个 属性,该视图模型拥有 ListBox 中的项目。看起来你在代码后面做所有事情,但你不应该这样。

#region MakeItemsLarge Property
private bool _makeItemsLarge = false;
public bool MakeItemsLarge
{
    get { return _makeItemsLarge; }
    set
    {
        if (value != _makeItemsLarge)
        {
            _makeItemsLarge = value;
            OnPropertyChanged();
        }
    }
}
#endregion MakeItemsLarge Property

现在给 DataTemplate 添加一个触发器来控制大小,并给 StackPanel 一个 x:Name 以便触发器在设置大小时可以引用它。

<DataTemplate>
    <StackPanel x:Name="OuterPanel" Margin="5" HorizontalAlignment="Center">
        <Image Margin="3" Source="{Binding path}" MouseDown="ImageClick_MouseDown" />
        <TextBlock TextAlignment="Center" Text="{Binding name}"/>
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger 
            Binding="{Binding DataContext.MakeItemsLarge, RelativeSource={RelativeSource AncestorType=ListBox}}"
            Value="True"
            >
            <Setter
                TargetName="OuterPanel"
                Property="Height"
                Value="400"
                />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

现在我们如何到达 MakeItemsLarge 属性:在 DataTemplate 中,绑定默认绑定到项目的属性——具有 [= 的东西21=] 属性 和一个 path 属性。但是 MakeItemsLargeparent 视图模型的 属性,它拥有 name/path 项的集合。那个viewmodel是ListBoxDataContext,所以我们去那里找一下。

如果您绝对拒绝对 MVVM 做任何事情,我可以告诉您如何使 MakeItemsLarge 成为 window 或用户控件的 DependencyProperty 或任何包含 ListBox,然后是如何使用 RelativeSource 绑定到视图本身的属性。

这是另一个不需要视图模型的选项:

这在视图中的某处:

<CheckBox
    x:Name="ChkLargeness"
    Content="Toggle Item Largeness"
    />

并且 DataTrigger 上的 Binding 更改为直接获取该复选框的选中状态。关于 DataTemplate 的其他所有内容都与上面相同。

<DataTrigger 
    Binding="{Binding IsChecked, ElementName=ChkLargeness}"
    Value="True"
    >

Also how do you go about returning the current size of the listbox items?

您可能真的不需要这些信息。但它将是 ListBoxItem 个实例中的 ActualSize 属性 个。可能与 DataTemplate.

StackPanelActualSize 的值相同

更新

因为 MakeItemsLargePage 的子类的成员,而不是视图模型的成员,让我们将其作为依赖项 属性 而不是 INPC/viewmodel 属性 以上:

#region MakeItemsLarge Property
public bool MakeItemsLarge
{
    get { return (bool)GetValue(MakeItemsLargeProperty); }
    set { SetValue(MakeItemsLargeProperty, value); }
}

public static readonly DependencyProperty MakeItemsLargeProperty =
    DependencyProperty.Register(nameof(MakeItemsLarge), typeof(bool), typeof(MovieChooser),
        new PropertyMetadata(false));
#endregion MakeItemsLarge Property

然后像这样绑定。请注意,它不是 ListBox 的数据上下文的 属性。它是 Page 本身的 属性。

Binding="{Binding MakeItemsLarge, RelativeSource={RelativeSource AncestorType=Page}}"