我的WPF应用程序出现问题,我不明白为什么。我与XAML的专家相距甚远,而且我不理解这个错误,甚至不知道代码的哪一部分会引发错误。
我有以下观点:
<DataGrid BorderThickness="0" Width="Auto" AutoGenerateColumns="False" AlternationCount="2"
IsSynchronizedWithCurrentItem="True" AutomationProperties.AutomationId="PositionSummaryGrid"
ItemsSource="{Binding Path=BOEList}" RowDetailsVisibilityMode="VisibleWhenSelected">
<DataGrid.Columns>
<DataGridTextColumn Header="BOE Reference" Binding="{Binding Path=Reference}"/>
<DataGridTextColumn Header="Account No" Binding="{Binding Path=AccountNo}"/>
<DataGridTextColumn Header="LBL Invoice No" Binding="{Binding Path=InvoiceNo}"/>
<DataGridTextColumn Header="Date Raised" Binding="{Binding Path=DateRaised}"/>
<DataGridTextColumn Header="Value" Binding="{Binding Converter={StaticResource currencyConverter}, Path=Value}" Width="85"/>
<DataGridTextColumn Header="Bank Charges" Binding="{Binding Converter={StaticResource currencyConverter}, Path=BankCharges}" Width="85"/>
<DataGridTextColumn Header="Payment Due" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentDue}" Width="85"/>
<DataGridTextColumn Header="Description" Binding="{Binding Path=Description}" Width="auto"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
使用以下方式设置样式:
<Style x:Key="DataGridScrollViewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Focusable="false">
<Border CornerRadius="4" Background="{StaticResource DefaultedBorderBrush}" Padding="4" Margin="0,4,0,4">
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"/>
</Border>
</ScrollViewer>
<ScrollContentPresenter Name="PART_ScrollContentPresenter" KeyboardNavigation.DirectionalNavigation="Local"/>
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridColumnHeaderGripper" TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="18"/>
<Setter Property="Background" Value="#404040"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
<Rectangle HorizontalAlignment="Center" Width="1" Fill="{TemplateBinding Background}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridColumnHeader}" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border Name="HeaderBorder" BorderThickness="0,1,0,1" BorderBrush="{x:Null}" Background="{x:Null}" Padding="2,0,2,0">
<ContentPresenter Name="HeaderContent" Margin="0,0,0,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0" Style="{StaticResource DataGridColumnHeaderGripper}" Foreground="#FFFFFFFF" Background="{x:Null}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
<Setter Property="Foreground" TargetName="PART_HeaderGripper" Value="#FFFCFCFC"/>
<Setter Property="Background" TargetName="HeaderBorder" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="HeaderContent" Property="Margin" Value="1,1,0,0"/>
<Setter Property="Foreground" TargetName="PART_HeaderGripper" Value="#FFE0E0E0"/>
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
<Setter Property="Background" TargetName="HeaderBorder" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background" TargetName="PART_HeaderGripper" Value="{x:Null}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGrid}" TargetType="{x:Type DataGrid}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="GridLinesVisibility" Value="None"/>
<Setter Property="SelectionMode" Value="Extended"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Name="Border" BorderThickness="1" BorderBrush="{x:Null}" Background="{x:Null}">
<ScrollViewer Style="{DynamicResource DataGridScrollViewer}" Foreground="#FFFFFFFF">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="#AAAAAA"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="#000000"/>
<Setter Property="DetailsVisibility" Value="Collapsed"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true" CornerRadius="4" Margin="0,4,0,0">
<SelectiveScrollingGrid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<DataGridDetailsPresenter SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"
Grid.Column="1" Grid.Row="1"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Grid.RowSpan="2"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}"/>
</SelectiveScrollingGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" TargetName="Border" Value="#A5FFFFFF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" TargetName="Border" Value="#01FFFFFF"></Setter>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Border" Value="#99B4C6"/>
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Border" Value="#c5d7e5"/>
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Rectangle Fill="White" Opacity="0"></Rectangle>
<ContentPresenter HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ViewModel是:
public class BoeListViewModel : Screen
{
#region Fields
private BOEManager _Manager;
private ObservableCollection<BOE> _boeList;
#endregion
#region Properties
public ObservableCollection<BOE> BOEList
{
get { return _boeList; }
set
{
_boeList = value;
NotifyOfPropertyChange(() => BOEList);
}
}
public string Header
{
get { return "CURRENT BOES"; }
}
#endregion
#region Constructor
public BoeListViewModel()
{
this.DisplayName = "Current BOEs";
_Manager = IoC.Get<BOEManager>();
BOEList = _Manager.load();
}
#endregion
BOE模型是一个简单的属性集合,包括:
public ObservableCollection<Payment> Payments
{
get { return _payments; }
set
{
if (value != _payments)
{
_payments = value;
NotifyOfPropertyChange(() => Payments);
}
}
}
再次付款一个简单的属性集合(这只是原型)。
似乎在Caliburn Micro的OnStartup()
方法中发生异常,但我并非100%确定。它是:
System.Windows.Markup.XamlParseException occurred
HResult=-2146233087
Message=Add value to collection of type 'System.Windows.Controls.ItemCollection' threw an exception.
Source=PresentationFramework
LineNumber=0
LinePosition=0
StackTrace:
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.UIElement.UpdateLayout()
at System.Windows.Interop.HwndSource.SetLayoutSize()
at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
at System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
at System.Windows.Window.SetRootVisual()
at System.Windows.Window.SetRootVisualAndUpdateSTC()
at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
at System.Windows.Window.CreateSourceWindowDuringShow()
at System.Windows.Window.SafeCreateWindowDuringShow()
at System.Windows.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.Show()
at Caliburn.Micro.WindowManager.ShowWindow(Object rootModel, Object context, IDictionary`2 settings) in c:\Users\Rob\Documents\CodePlex\caliburnmicro\src\Caliburn.Micro.WPF\WindowManager.cs:line 75
InnerException: System.InvalidOperationException
HResult=-2146233079
Message=Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.
Source=PresentationFramework
StackTrace:
at System.Windows.Controls.ItemCollection.CheckIsUsingInnerView()
at System.Windows.Controls.ItemCollection.Add(Object newItem)
at System.Xaml.Schema.XamlTypeInvoker.AddToCollection(Object instance, Object item)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.Add(Object collection, XamlType collectionType, Object value, XamlType valueXamlType)
InnerException:
抱歉代码转储,但我不知道这段代码导致错误的部分,因为它只是抛出没有位置的错误,我相当肯定与{{{ 1}},如果没有RowDetails
这没有问题,但是我不能为我的生活找出正在发生的事情。
另外,如果有人可以让我知道如何追踪这类错误?
编辑:
两件事。
删除行RowDetails
允许应用程序无异常地运行,但显然从未显示详细信息行。
其次,注释掉DataGrid行样式中的RowDetailsVisibilityMode="VisibleWhenSelected"
也具有允许它运行的相同效果,因此它必须与此类似,但是该代码直接来自Microsoft示例。
答案 0 :(得分:17)
您的问题是您没有以适当的方式定义列。
添加 DataGrid.Columns 标记
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGrid.Columns>
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
答案 1 :(得分:5)
问题是:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Payments}">
<DataGridTextColumn Header="Payment Date" Binding="{Binding PaymentDate}"/>
<DataGridTextColumn Header="Payment Amount" Binding="{Binding Converter={StaticResource currencyConverter}, Path=PaymentAmount}"/>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
显然,只要我将数据网格移动到样式表并使用它工作的ItemTemplate绑定它,就不能直接在xaml页面中为集合定义数据窗口。
<ItemsControl ItemsSource="{Binding Payments}" ItemTemplate="{StaticResource PaymentItemTemplate}"/>
我认为它抱怨的itemcollection是包含views控件的那个,并且它在运行时在单行内创建多个元素时会出现问题。