c# - WPF 在触发器上更改 Grid.ColumnSpan

标签 c# wpf xaml mvvm

<分区>

tl;dr:如果选择了 2 个项目,我希望详细 View 显示在 2 列中,如果只选择了 1 个项目,则希望详细 View 显示在 2 列中。

我有一个 DockPanel,左边有 2 个 ListBox,右边有一个 2 列的 Grid。

当在 listBox1 中选择一个项目时,我在网格的第 0 列中显示详细信息 View 。

当在 listBox2 中选择一个项目时,我会在网格的第 1 列中显示详细信息 View 。

    <DockPanel>

        <StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
            <ListBox x:Name="listBox1" ItemsSource="{Binding Items1}" SelectedItem="{Binding SelectedItem1}"/>                    
            <ListBox x:Name="listBox2" ItemsSource="{Binding Items2}" SelectedItem="{Binding SelectedItem2}"/>
        </StackPanel>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <ContentControl Grid.Column="0" Content="{Binding SelectedItem1}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}"/>
            <ContentControl Grid.Column="1" Content="{Binding SelectedItem2}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}"/>
        </Grid>

    </DockPanel>

这很好用。但是,我想对其进行修改,以便当在一个列表框中选择了一个项目但在另一个列表框中没有选择时,详细信息 View 将跨越两个网格列

我的第一个想法是创建几个 DataTriggers,它们根据 ListBoxes 的 SelectedIndex 修改 ContentControls 的 ColumnSpan。

这对于通常位于 Grid.Column="0"中的详细信息 View 来说效果很好。但是,它不适用于通常位于 Grid.Column="1"中的详细信息 View ,因为原始列号是硬编码的:

            <ContentControl Grid.Column="0" Content="{Binding SelectedItem1}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}">
                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=listBox2, Path=SelectedIndex}" Value="-1">
                                <Setter Property="Grid.ColumnSpan" Value="2"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>

            <ContentControl Grid.Column="1" Content="{Binding SelectedItem2}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}">
                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=listBox1, Path=SelectedIndex}" Value="-1">
                                <!--Can't modify Grid.Column since it's hardcoded above!-->
                                <Setter Property="Grid.Column" Value="0"/>
                                <Setter Property="Grid.ColumnSpan" Value="2"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>

如果我可以创建一个可以与 ListBox.SelectedIndex(即 >=0)进行值比较的 DataTrigger,那么我可以首先避免对列号进行硬编码。

有没有办法在 XAML 中做这样的事情?

最佳答案

您总是可以使用隐藏元素绑定(bind)技巧。下面的例子,你只要把 bindme 改成 2,Grids span 就会改变。我对所有类型的东西都这样做,你不能用 Storyboard制作动画。

关于c# - WPF 在触发器上更改 Grid.ColumnSpan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1848329/

相关文章:

c# - AT 调制解调器命令有什么作用?

c# - Dapper 读取 SqlHierachyId 列(SQL Server 2008 R2)

c# - wpf.DataGrid 中的自动行高

c# - 渲染和打印 HTML 到非默认打印机

WPF - 将 IsMouseOver 绑定(bind)到可见性

c# - Windows Universal 中的 MediaElement 样式

android - 我需要在 Xamarin Forms 按钮内设置格式化文本(两种不同大小)

c# - WPF 如何从 ViewModel 访问控件

c# - Xamarin 表单如何重叠?

c# - 在 C# Winforms 中使用多线程的响应式 GUI