首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在分组选项更改时保持DataGrid的列宽

在分组选项更改时保持DataGrid的列宽
EN

Stack Overflow用户
提问于 2018-03-24 15:43:56
回答 1查看 46关注 0票数 0

我已经使用Rubberduck一段时间来改进我的VBA代码了。这只鸭子向我介绍了单元测试和许多其他适当的技术。出于感激,我试图回馈并为我发现的一个问题贡献一个解决方案,尽管我并不了解C#。

此问题与System.Windows.Controls.Grid有关。网格有一个选项,可以按结果或所在模块对测试结果进行分组。如果调整了列宽,然后更改了分组,则不会反映宽度更改。

我已经在视图模型上创建了一些属性,我认为这些属性将允许双向绑定,其中一个示例如下所示。

代码语言:javascript
复制
private DataGridLength _outcomeColumnWidth;
public DataGridLength OutcomeColumnWidth
{
    get => _outcomeColumnWidth;
    set
    {
        _outcomeColumnWidth = value;
        OnPropertyChanged();
    } 
}

我编辑了XAML,试图创建一个TwoWay绑定,使更改后的列宽在分组更改后保持不变。

代码语言:javascript
复制
<Grid>
    <controls:GroupingGrid ItemsSource="{Binding Source={StaticResource ResultsByOutcome}}"
                                SelectedItem="{Binding SelectedTest}"
                                ShowGroupingItemCount="True"
                                Visibility="{Binding IsChecked, ElementName=GroupByOutcome, Converter={StaticResource BoolToVisibility}}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Outcome}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="unitTesting:TestMethod">
                        <Image Source="{Binding Result.Outcome, Converter={StaticResource OutcomeIconConverter}}" Height="16" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_QualifiedModuleName}" Binding="{Binding Declaration.QualifiedName.QualifiedModuleName}"
                                Width="{Binding OutcomeColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_MethodName}" Binding="{Binding Declaration.IdentifierName}"
                                Width="{Binding ModuleColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Message}" Binding="{Binding Result.Output}"
                                Width="{Binding MessageColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Duration}" Binding="{Binding Result.Duration, StringFormat={}{0}ms}" 
                                Width="{Binding DurationColumnWidth, Mode=TwoWay}"/>
        </DataGrid.Columns>
    </controls:GroupingGrid>
    <controls:GroupingGrid ItemsSource="{Binding Source={StaticResource ResultsByModule}}"
                                SelectedItem="{Binding SelectedTest}"
                                ShowGroupingItemCount="True"
                                Visibility="{Binding IsChecked, ElementName=GroupByLocation, Converter={StaticResource BoolToVisibility}}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Outcome}">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="unitTesting:TestMethod">
                        <Image Source="{Binding Result.Outcome, Converter={StaticResource OutcomeIconConverter}}" Height="16" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_QualifiedModuleName}" Binding="{Binding Declaration.QualifiedName.QualifiedModuleName}" 
                                Width="{Binding OutcomeColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_MethodName}" Binding="{Binding Declaration.QualifiedName.MemberName}" 
                                Width="{Binding ModuleColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Message}" Binding="{Binding Result.Output}"
                                Width="{Binding MessageColumnWidth, Mode=TwoWay}"/>
            <DataGridTextColumn Header="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=TestExplorer_Duration}" Binding="{Binding Result.Duration, StringFormat={}{0}ms}"
                                Width="{Binding DurationColumnWidth, Mode=TwoWay}"/>
        </DataGrid.Columns>
    </controls:GroupingGrid>
</Grid>

视图模型继承自实现INotifyPropertyChanged的抽象类ViewModelBase。抽象类还有public event PropertyChangedEventHandler PropertyChangedOnPropertyChanged方法。我已经在getset上为该属性设置了断点,但这两个断点都没有到达。

EN

回答 1

Stack Overflow用户

发布于 2018-07-18 18:53:18

DataGrid列不是逻辑或可视化树的一部分,因为它们是抽象对象,因此它们不能访问ViewModel的DataContext。这使得它们很难绑定。好消息是,有几种方法可以做到这一点。

代理对象

代码语言:javascript
复制
<UserControl.Resources>
    <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
</UserControl.Resources>

<Grid>
    <DataGrid ItemsSource="{Binding Descriptions}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Description"
                                Width="{Binding Source={StaticResource ProxyElement}, Path=Width, Mode=TwoWay}"
                                Binding="{Binding Description}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

为了进一步阅读,我建议您看一下https://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/,因为它很好地概述了原因,并使用他创建的特定ProxyClass提供了上述代码的替代方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49462431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档