我已经使用Rubberduck一段时间来改进我的VBA代码了。这只鸭子向我介绍了单元测试和许多其他适当的技术。出于感激,我试图回馈并为我发现的一个问题贡献一个解决方案,尽管我并不了解C#。
此问题与System.Windows.Controls.Grid有关。网格有一个选项,可以按结果或所在模块对测试结果进行分组。如果调整了列宽,然后更改了分组,则不会反映宽度更改。
我已经在视图模型上创建了一些属性,我认为这些属性将允许双向绑定,其中一个示例如下所示。
private DataGridLength _outcomeColumnWidth;
public DataGridLength OutcomeColumnWidth
{
get => _outcomeColumnWidth;
set
{
_outcomeColumnWidth = value;
OnPropertyChanged();
}
}我编辑了XAML,试图创建一个TwoWay绑定,使更改后的列宽在分组更改后保持不变。
<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 PropertyChanged和OnPropertyChanged方法。我已经在get和set上为该属性设置了断点,但这两个断点都没有到达。
发布于 2018-07-18 18:53:18
DataGrid列不是逻辑或可视化树的一部分,因为它们是抽象对象,因此它们不能访问ViewModel的DataContext。这使得它们很难绑定。好消息是,有几种方法可以做到这一点。
代理对象
<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提供了上述代码的替代方案。
https://stackoverflow.com/questions/49462431
复制相似问题