【问题标题】:WPF UniformGrid dynamic contentWPF UniformGrid 动态内容
【发布时间】:2020-03-02 18:35:09
【问题描述】:

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

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>

样本输出

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

这是一个正确的输出

谢谢!

【问题讨论】:

    标签: c# wpf view grid uniformgrid


    【解决方案1】:

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

    public MainWindowViewModel()
    {
        SelectedIndex = 0;
    }
    

    顺便说一句,Grid.RowGrid.Column 在 UniformGrid 中无效。 UniformGrid 按照添加的顺序排列项目

    不要在 UserControls 中设置 DataContext。

    而不是 Visibility[] 在 MainWindowViewModel (ObservableCollection&lt;ScreenViewModel&gt;) 中创建 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

    【讨论】:

    • 没有灰,它没用。我添加了您的建议,但输出仍然相同。当我更改组合框中的索引时,它仍然在屏幕上显示所有 6 个文本。如果我选择 1,我期望 1,而不是 6。
    • @Tim,我无法重现
    • 我想不通。我仍然有这个问题。可以和我分享你的解决方案吗?
    • "你有没有可能把你的解决方案分享给我" - 我在 VS 中创建了新的 WPF 项目,从问题中复制了代码并用 PropertyChanged 调用替换了SetProperty,因为我没有导入 Prism 包。就这样。项目目标 .net 4.5.2
    • 好的,我发现了问题。在我的 ScreenView.xml 我也有这个 但是为什么这段代码会把 UI 搞砸???这是非常标准的,我的视图模型需要它来做一些绑定。
    猜你喜欢
    • 2011-05-24
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多