2016-04-23 101 views
1

我試圖創建一次可以播放多個視頻的視頻播放器。我已經讓玩家工作,現在我試圖讓用戶在運行時添加更多視頻。我使用統一網格顯示視頻,該視頻使用轉換器根據視頻數量決定應該生成多少行和多少列。當你在運行之前定義有多少玩家時,它可以正常工作,但是當我在添加玩家的同時運行統一網格不會更新行或列時。它只是將其他視頻添加到之前的任何結構中。無論如何,我可以強迫它重新評估行/列?重新評估UniformGrid行和列WPF

TL; DR:我可以在查看時重新評估統一網格的行和列嗎?怎麼樣 ?

該控件的xaml位於下方。 其他信息來源,可能是有用的:
1.運動員是一個ObservableCollection正在呈現與一個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> 
+0

http://stackoverflow.com/questions/15178726/setting-rows-of-itempaneltemplate-uniformgrid-through-c-sharp – StepUp

+0

你養'的PropertyChanged( 「玩家」)'每次*計數*玩家的變化?因爲我看不到任何可以告訴那些綁定在計數改變時更新的東西。如果您可以重寫CountToColumns和CountToRows來獲取int,那麼您可以使用'{Binding Items.Count,RelativeSource = {RelativeSource Self}},Converter = {StaticResource CountToColumns}}'。 –

+0

其實劃傷:我只是測試它和'行= {綁定的球員。Count}'完全適合我 - 如果'Players'是一個'ObservableCollection'。是嗎?如果是這樣,我只需重寫那些轉換器,以Players.Count爲模,就可以完成了。 –

回答

0

這個問題似乎是沒有什麼是通知所述裝訂
2.控制該數量Players中的項目發生了變化:綁定正在等待您的視圖模型告訴它有一個新的Players集合。

但是因爲PlayersObservableCollection,所以在Count更改時會增加PropertyChanged。所以,最簡單的例子:

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

我下面的作品更新的行和列數爲項目添加到Players。在轉換器中的算術可以使用一點點的工作,但重要的是綁定更新UniformGrid.RowsUniformGrid.Columns每次Players更改。這是可行的,因爲ObservableCollection每次添加或刪除項目時都會提高PropertyChanged("Count")。因爲我綁定到ObservableCollection的屬性,所以綁定訂閱ObservableCollectionPropertyChanged事件,所以它知道在Count更改時更新。

C#

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(); 
    } 
} 

XAML

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

    <ItemsControl 
     Grid.Row="1" 
     ItemsSource="{Binding Players}" 
     > 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <UniformGrid 
        Rows="{Binding Players.Count, Converter={StaticResource RowsColumns}}" 
        Columns="{Binding Players.Count, Converter={StaticResource RowsColumns}}" 
        /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 

    <StackPanel Grid.Row="0" Orientation="Horizontal"> 
     <Button 
      Content="Add Player" 
      Click="AddButton_Click" 
      Margin="2" 
      Width="100" 
      /> 
     <Button 
      Content="Remove Player" 
      Click="RemoveButton_Click" 
      Margin="2" 
      Width="100" 
      /> 
    </StackPanel> 
</Grid> 
+0

我想我應該提到玩家是一個ObservableCollection,並且它肯定是通過綁定更新的,因爲我得到更多玩家出現,它的佈局就是錯誤的 –

+0

@ScottMaher你說你看到了網格中的項目,所以我認爲可能是這種情況。 –

+0

嘿,你的評論暗示我直接綁定到伯爵就像一個魅力。如果你將編輯你的答案包括它,我會接受你的答案:) –

1

設置RowsColumns是沒有必要的。沒有他們,一切都會奏效。 UniformGrid將一切放在任何容器內。

如果仍然想要使用Binding,那麼下面的作品適合我,Cols在這裏是固定的。 Converters不需要。

void Players_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     Rows = (int)Math.Ceiling(Players.Count/Cols); 
    }