重新评估UniformGrid行和列WPF

时间:2016-04-23 20:28:17

标签: c# wpf mvvm uniformgrid

我正在尝试创建一个可以同时播放多个视频的视频播放器。我已经让玩家工作了,现在我试图让用户在运行时添加其他视频。我在统一网格中显示视频,该网格使用转换器根据视频数量决定应生成多少行和列。当你在运行之前定义有多少玩家时它可以正常工作,但是当我在运行时添加一个玩家时,统一网格不会更新行或列。它只是为之前的任何结构添加了另一个视频。反正我是否可以强制它重新评估行/列?

TL; DR:在查看统一网格时,我可以重新评估统一网格的行和列吗?怎么样?

控件的xaml如下。 可能有用的其他信息:
1.玩家是ObservableCollection
2.控件正在显示一个TabControl

<UserControl x:Class="Views.AllVideos"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-Views"
             mc:Ignorable="d">
  <ItemsControl ItemsSource="{Binding Players}"
                x:Name="AllVideosControl">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <UniformGrid Columns="{Binding Players, Converter={StaticResource CountToColumns}, Mode=OneWay}"
                     Rows="{Binding Players, Converter={StaticResource CountToRows}, Mode=OneWay}"
                     VerticalAlignment="Stretch"
                     HorizontalAlignment="Stretch"
                     IsItemsHost="True"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Border BorderBrush="{DynamicResource AccentBrush}"
                BorderThickness="1"
                Margin="5">
          <ls:PanelPreview DataContext="{Binding}"/>
        </Border>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</UserControl>

2 个答案:

答案 0 :(得分:1)

根本不需要设置RowsColumns。没有它们,一切都会奏效。 UniformGrid会将所有内容统一放在任何容器内。

如果您仍想使用Binding,那么以下方法适用于我,Cols在此处已修复。 <{1}}不需要。

Converters

答案 1 :(得分:0)

问题似乎是没有任何东西通知绑定Players中的项目数已经改变:Binding坐在那里等待你的viewmodel告诉它有一个新的Players集合。

但由于PlayersObservableCollection,因此当PropertyChanged更改时,它会引发Count。所以,最简单的情况:

<UniformGrid
    Rows="{Binding Players.Count}"
    ...
    />

以下内容适用于我在项目添加到Players时更新行数和列数。转换器中的算法可以使用一些工作,但关键是每次UniformGrid.Rows更改时绑定都会更新UniformGrid.ColumnsPlayers。这是有效的,因为ObservableCollection每次添加或删除项目时都会引发PropertyChanged("Count")。因为我绑定到ObservableCollection的属性,所以绑定会订阅ObservableCollection的{​​{1}}事件,因此它知道在PropertyChanged更改时更新。

C#

Count

XAML

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void AddButton_Click(object sender, RoutedEventArgs e)
    {
        (DataContext as ViewModel).Players.Add($"Player {(DataContext as ViewModel).Players.Count + 1}");
    }

    private void RemoveButton_Click(object sender, RoutedEventArgs e)
    {
        if ((DataContext as ViewModel).Players.Count > 0)
            (DataContext as ViewModel).Players.RemoveAt(0);
    }
}

public class ViewModel
{
    private ObservableCollection<String> _players = new ObservableCollection<string>();
    public ObservableCollection<String> Players
    {
        get { return _players; }
    }
}

public class RowsColumnsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Math.Ceiling(Math.Sqrt((int)value));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}