WPF UniformGrid 动态内容
WPF UniformGrid dynamic content
我有一个 uniformgrid,我想动态显示它 contents/view。
它可以显示 1、2、4 或 6 个内容。我设置了 uniformgrid 行、col 绑定和内容可见性绑定。
这在 views/contents 的情况下不起作用,
但它确实适用于矩形的情况。这是为什么?
我如何修改它以使用 views/contents。
示例 MainWindow.xaml 代码.....
<StackPanel>
<ComboBox HorizontalAlignment="Left" Width="50" SelectedIndex="{Binding SelectedIndex}">
<ComboBoxItem IsSelected="True" Content="1" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="6" />
</ComboBox>
<!-- NOT CORRECT, SHOWS 6 ITEMS ALWAYS -->
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}">
<local:ScreenView Grid.Row="0" Grid.Column="0" Visibility="{Binding VisibleScreen[0]}" />
<local:ScreenView Grid.Row="0" Grid.Column="1" Visibility="{Binding VisibleScreen[1]}" />
<local:ScreenView Grid.Row="0" Grid.Column="2" Visibility="{Binding VisibleScreen[2]}" />
<local:ScreenView Grid.Row="1" Grid.Column="0" Visibility="{Binding VisibleScreen[3]}" />
<local:ScreenView Grid.Row="1" Grid.Column="1" Visibility="{Binding VisibleScreen[4]}" />
<local:ScreenView Grid.Row="1" Grid.Column="2" Visibility="{Binding VisibleScreen[5]}" />
</UniformGrid>
<!-- OK, SHOWS 1,2,4, or 6 RECT DEPENDING ON SelectedIndex -->
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}">
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="0" Fill="Red" Visibility="{Binding VisibleScreen[0]}" />
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="1" Fill="Orange" Visibility="{Binding VisibleScreen[1]}" />
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="2" Fill="Yellow" Visibility="{Binding VisibleScreen[2]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="0" Fill="Green" Visibility="{Binding VisibleScreen[3]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="1" Fill="Blue" Visibility="{Binding VisibleScreen[4]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="2" Fill="Violet" Visibility="{Binding VisibleScreen[5]}" />
</UniformGrid>
</StackPanel>
基本上,我有一个组合框。如果我 select 1,我的 ViewModel 将动态更改 rows=1,cols=1,第一个内容可见,其他内容崩溃。它适用于矩形,但不适用于视图。这是为什么?如何修复它以使其适用于视图?
任何好奇的人,这是 MainWindowViewModel
中的代码(Prism MVVM)
class MainWindowViewModel : BindableBase
{
private const int SCREEN_MAX = 6;
private int screenRows = 1;
public int ScreenRows
{
get { return screenRows; }
set { SetProperty(ref screenRows, value); }
}
private int screenCols = 1;
public int ScreenCols
{
get { return screenCols; }
set { SetProperty(ref screenCols, value); }
}
private Visibility[] visibleScreen = new Visibility[SCREEN_MAX];
public Visibility[] VisibleScreen
{
get { return visibleScreen; }
set { SetProperty(ref visibleScreen, value); }
}
private int selectedIndex;
public int SelectedIndex
{
get { return selectedIndex; }
set
{
SetProperty(ref selectedIndex, value);
ChangeScreen(selectedIndex);
}
}
private void ShowScreens(int num_screens)
{
// make all collapse
for (int i = 0; i < SCREEN_MAX; i++)
VisibleScreen[i] = Visibility.Collapsed;
// show only X num screens
for (int i = 0; i < num_screens; i++)
VisibleScreen[i] = Visibility.Visible;
RaisePropertyChanged("VisibleScreen");
}
public void ChangeScreen(int idx)
{
switch (idx)
{
case 0: ScreenRows = 1; ScreenCols = 1; ShowScreens(1); break;
case 1: ScreenRows = 1; ScreenCols = 2; ShowScreens(2); break;
case 2: ScreenRows = 2; ScreenCols = 2; ShowScreens(4); break;
case 3: ScreenRows = 2; ScreenCols = 3; ShowScreens(6); break;
}
}
}
ScreenView.xaml
<UserControl...>
<!-- SOME HOW IT IS THIS DATACONTEXT CODE MESS UP THE UI -->
<UserControl.DataContext>
<local:ScreenViewModel x:Name="vm"/>
</UserControl.DataContext>
<StackPanel>
<TextBlock>TEST</TextBlock>
</StackPanel>
</UserControl>
示例输出
正如您从示例输出中看到的那样,我的组合 selection 是 1,因此它应该显示 1 个 TEST,而 1 个正方形显示哪个是正确的。但它为什么要显示 6 TEST?如何让它显示 1 个测试?
这是正确的输出
谢谢!
selectedIndex
的初始值为0(int字段的默认值)。但是 VisibleScreen 数组的内容与 selectedIndex 不匹配 - 您需要在初始化期间调用 ChangeScreen,例如像这样:
public MainWindowViewModel()
{
SelectedIndex = 0;
}
顺便说一句,Grid.Row
和 Grid.Column
在 UniformGrid 中没有效果。 UniformGrid 按照添加的顺序排列项目
不要在 UserControls 中设置 DataContext。
而不是 Visibility[]
在 MainWindowViewModel (ObservableCollection<ScreenViewModel>
) 中创建 ScreenViewModel 的集合。
在ScreenViewModel
中添加bool IsVisible
属性。
像这样更改 ShowScreens 方法:
private void ShowScreens(int num_screens)
{
for (int i = 0; i < SCREEN_MAX; i++)
VisibleScreen[i].IsVisible = i < num_screens ? Visibility.Visible : Visibility.Collapsed;
}
更改视图:
<ItemsControl ItemsSource="{Binding VisibleScreen}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<local:ScreenView Visibility="{Binding IsVisible}"/>
</ItemsControl.ItemTemplate>
</ItemsControl>
ItemTemplate 将为 VisibleScreen 集合中的每个项目创建一个 local:ScreenView,并将其分配给 local:ScreenView
的 DataContext
我有一个 uniformgrid,我想动态显示它 contents/view。 它可以显示 1、2、4 或 6 个内容。我设置了 uniformgrid 行、col 绑定和内容可见性绑定。 这在 views/contents 的情况下不起作用, 但它确实适用于矩形的情况。这是为什么? 我如何修改它以使用 views/contents。 示例 MainWindow.xaml 代码.....
<StackPanel>
<ComboBox HorizontalAlignment="Left" Width="50" SelectedIndex="{Binding SelectedIndex}">
<ComboBoxItem IsSelected="True" Content="1" />
<ComboBoxItem Content="2" />
<ComboBoxItem Content="4" />
<ComboBoxItem Content="6" />
</ComboBox>
<!-- NOT CORRECT, SHOWS 6 ITEMS ALWAYS -->
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}">
<local:ScreenView Grid.Row="0" Grid.Column="0" Visibility="{Binding VisibleScreen[0]}" />
<local:ScreenView Grid.Row="0" Grid.Column="1" Visibility="{Binding VisibleScreen[1]}" />
<local:ScreenView Grid.Row="0" Grid.Column="2" Visibility="{Binding VisibleScreen[2]}" />
<local:ScreenView Grid.Row="1" Grid.Column="0" Visibility="{Binding VisibleScreen[3]}" />
<local:ScreenView Grid.Row="1" Grid.Column="1" Visibility="{Binding VisibleScreen[4]}" />
<local:ScreenView Grid.Row="1" Grid.Column="2" Visibility="{Binding VisibleScreen[5]}" />
</UniformGrid>
<!-- OK, SHOWS 1,2,4, or 6 RECT DEPENDING ON SelectedIndex -->
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}">
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="0" Fill="Red" Visibility="{Binding VisibleScreen[0]}" />
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="1" Fill="Orange" Visibility="{Binding VisibleScreen[1]}" />
<Rectangle Width="20" Height="20" Grid.Row="0" Grid.Column="2" Fill="Yellow" Visibility="{Binding VisibleScreen[2]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="0" Fill="Green" Visibility="{Binding VisibleScreen[3]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="1" Fill="Blue" Visibility="{Binding VisibleScreen[4]}" />
<Rectangle Width="20" Height="20" Grid.Row="1" Grid.Column="2" Fill="Violet" Visibility="{Binding VisibleScreen[5]}" />
</UniformGrid>
</StackPanel>
基本上,我有一个组合框。如果我 select 1,我的 ViewModel 将动态更改 rows=1,cols=1,第一个内容可见,其他内容崩溃。它适用于矩形,但不适用于视图。这是为什么?如何修复它以使其适用于视图?
任何好奇的人,这是 MainWindowViewModel
中的代码(Prism MVVM)class MainWindowViewModel : BindableBase
{
private const int SCREEN_MAX = 6;
private int screenRows = 1;
public int ScreenRows
{
get { return screenRows; }
set { SetProperty(ref screenRows, value); }
}
private int screenCols = 1;
public int ScreenCols
{
get { return screenCols; }
set { SetProperty(ref screenCols, value); }
}
private Visibility[] visibleScreen = new Visibility[SCREEN_MAX];
public Visibility[] VisibleScreen
{
get { return visibleScreen; }
set { SetProperty(ref visibleScreen, value); }
}
private int selectedIndex;
public int SelectedIndex
{
get { return selectedIndex; }
set
{
SetProperty(ref selectedIndex, value);
ChangeScreen(selectedIndex);
}
}
private void ShowScreens(int num_screens)
{
// make all collapse
for (int i = 0; i < SCREEN_MAX; i++)
VisibleScreen[i] = Visibility.Collapsed;
// show only X num screens
for (int i = 0; i < num_screens; i++)
VisibleScreen[i] = Visibility.Visible;
RaisePropertyChanged("VisibleScreen");
}
public void ChangeScreen(int idx)
{
switch (idx)
{
case 0: ScreenRows = 1; ScreenCols = 1; ShowScreens(1); break;
case 1: ScreenRows = 1; ScreenCols = 2; ShowScreens(2); break;
case 2: ScreenRows = 2; ScreenCols = 2; ShowScreens(4); break;
case 3: ScreenRows = 2; ScreenCols = 3; ShowScreens(6); break;
}
}
}
ScreenView.xaml
<UserControl...>
<!-- SOME HOW IT IS THIS DATACONTEXT CODE MESS UP THE UI -->
<UserControl.DataContext>
<local:ScreenViewModel x:Name="vm"/>
</UserControl.DataContext>
<StackPanel>
<TextBlock>TEST</TextBlock>
</StackPanel>
</UserControl>
示例输出
正如您从示例输出中看到的那样,我的组合 selection 是 1,因此它应该显示 1 个 TEST,而 1 个正方形显示哪个是正确的。但它为什么要显示 6 TEST?如何让它显示 1 个测试?
这是正确的输出
谢谢!
selectedIndex
的初始值为0(int字段的默认值)。但是 VisibleScreen 数组的内容与 selectedIndex 不匹配 - 您需要在初始化期间调用 ChangeScreen,例如像这样:
public MainWindowViewModel()
{
SelectedIndex = 0;
}
顺便说一句,Grid.Row
和 Grid.Column
在 UniformGrid 中没有效果。 UniformGrid 按照添加的顺序排列项目
不要在 UserControls 中设置 DataContext。
而不是 Visibility[]
在 MainWindowViewModel (ObservableCollection<ScreenViewModel>
) 中创建 ScreenViewModel 的集合。
在ScreenViewModel
中添加bool IsVisible
属性。
像这样更改 ShowScreens 方法:
private void ShowScreens(int num_screens)
{
for (int i = 0; i < SCREEN_MAX; i++)
VisibleScreen[i].IsVisible = i < num_screens ? Visibility.Visible : Visibility.Collapsed;
}
更改视图:
<ItemsControl ItemsSource="{Binding VisibleScreen}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding ScreenRows}" Columns="{Binding ScreenCols}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<local:ScreenView Visibility="{Binding IsVisible}"/>
</ItemsControl.ItemTemplate>
</ItemsControl>
ItemTemplate 将为 VisibleScreen 集合中的每个项目创建一个 local:ScreenView,并将其分配给 local:ScreenView
的 DataContext