Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF UniformGrid动态内容_C#_Wpf_View_Grid_Uniformgrid - Fatal编程技术网

C# WPF UniformGrid动态内容

C# WPF UniformGrid动态内容,c#,wpf,view,grid,uniformgrid,C#,Wpf,View,Grid,Uniformgrid,我有一个uniformgrid,我想动态显示内容/视图。 它可以显示1、2、4或6个内容。我设置了uniformgrid行、列绑定和内容可见性绑定。 这在视图/内容的情况下不起作用, 但它在矩形的情况下确实有效。为什么呢? 如何修改它以使用视图/内容。 示例MainWindow.xaml代码 <StackPanel> <ComboBox HorizontalAlignment="Left" Width="50" SelectedIndex="{Binding Selec

我有一个uniformgrid,我想动态显示内容/视图。 它可以显示1、2、4或6个内容。我设置了uniformgrid行、列绑定和内容可见性绑定。 这在视图/内容的情况下不起作用, 但它在矩形的情况下确实有效。为什么呢? 如何修改它以使用视图/内容。 示例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>

基本上,我有一个组合框。如果选择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;
        }
    }
}
<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>
class MainWindowViewModel:BindableBase
{
专用常量int屏幕_MAX=6;
私有int screenRows=1;
公共整数屏幕行
{
获取{返回屏幕行;}
set{SetProperty(ref screenRows,value);}
}
私有int screenCols=1;
公共int ScreenCols
{
获取{return screenCols;}
set{SetProperty(ref screenCols,value);}
}
私有可见性[]visibleScreen=新可见性[SCREEN_MAX];
公众能见度[]可视屏幕
{
获取{return visibleScreen;}
set{SetProperty(ref visibleScreen,value);}
}
私有int-selectedIndex;
公共整数选择索引
{
获取{return selectedIndex;}
设置
{ 
SetProperty(参考selectedIndex,值);
更改屏幕(选择索引);
}
}
私有无效显示屏幕(int num_屏幕)
{
//崩溃
对于(int i=0;i
屏幕视图.xaml

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

试验
样本输出

正如您可以从示例输出中看到的,我的组合选择是1,所以它应该显示1个TEST,而1个正方形显示哪个是正确的。但为什么要让我看6级考试呢?如何让它显示1个测试

这是一个corect输出


谢谢

selectedIndex的初始值为0(int字段的默认值)。但是VisibleScreen数组的内容与selectedIndex不匹配-您需要在初始化期间调用ChangeScreen,例如:

public MainWindowViewModel()
{
    SelectedIndex = 0;
}
private void ShowScreens(int num_screens)
{
    for (int i = 0; i < SCREEN_MAX; i++)
        VisibleScreen[i].IsVisible = i < num_screens ? Visibility.Visible : Visibility.Collapsed;
}
顺便说一句,
Grid.Row
Grid.Column
在UniformGrid中无效。UniformGrid按项目添加的顺序排列项目

不要在UserControls内设置DataContext

而不是在MainWindowViewModel中创建的ScreenViewModel集合(
ObservableCollection

ScreenViewModel
中添加
bool IsVisible
属性

更改ShowScreens方法如下:

public MainWindowViewModel()
{
    SelectedIndex = 0;
}
private void ShowScreens(int num_screens)
{
    for (int i = 0; i < SCREEN_MAX; i++)
        VisibleScreen[i].IsVisible = i < num_screens ? Visibility.Visible : Visibility.Collapsed;
}
private void显示屏幕(int num_屏幕)
{
对于(int i=0;i
更改视图:

<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

不,它不起作用。我添加了你的建议,但结果仍然是一样的。当我在组合框中更改索引时,它仍然在屏幕上显示所有6个文本。如果我选择1,我期望的是1,而不是6。@Tim,我无法复制,我想不出来。我还有这个问题。您是否可以将您的解决方案共享给我?“您是否可以将您的解决方案共享给我”-我在VS中创建了新的WPF项目,从问号中复制了代码,并用PropertyChanged调用替换了
SetProperty
,因为我没有导入Prism包。这就是全部。Project targets.NET4.5.2Ok,我发现了问题。在我的ScreenView.xml中,我也有这样的代码,但是为什么这些代码会把UI搞得一团糟呢???这是非常标准的,我需要它来为我的视图模型做一些绑定。