ListView custom view binding errors when MahApps.Metro referenced - wpf

Application I work on is WPF/.Net Core 3.1. It uses ListView with custom View (that show items in WrapPanel). Everything works fine until I add reference to MahApps.Metro and include necessary MahApps.Metro resources in App. Afterwards ListView functionality breaks up, items are not longer shown as in WrapPanel, just as ordinary list...
Also I get following errors in debug output:
System.Windows.Data Error: 40 : BindingExpression path error: 'Columns' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.Columns; DataItem='ScrollViewer' (Name=''); target element is 'ScrollViewer' (Name=''); target property is 'NoTarget' (type 'Object')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderContainerStyle' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderContainerStyle; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderContainerStyle' (type 'Style')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderTemplate' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderTemplate; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderTemplate' (type 'DataTemplate')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderTemplateSelector' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderTemplateSelector; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderTemplateSelector' (type 'DataTemplateSelector')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderStringFormat' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderStringFormat; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderStringFormat' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'AllowsColumnReorder' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.AllowsColumnReorder; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'AllowsColumnReorder' (type 'Boolean')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderContextMenu' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderContextMenu; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderContextMenu' (type 'ContextMenu')
System.Windows.Data Error: 40 : BindingExpression path error: 'ColumnHeaderToolTip' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.ColumnHeaderToolTip; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name=''); target property is 'ColumnHeaderToolTip' (type 'Object')
System.Windows.Data Error: 40 : BindingExpression path error: 'Columns' property not found on 'object' ''TileView' (HashCode=8352109)'. BindingExpression:Path=TemplatedParent.View.Columns; DataItem='ScrollViewer' (Name=''); target element is 'GridViewHeaderRowPresenter' (Name='PART_HeaderRowPresenter'); target property is 'Columns' (type 'GridViewColumnCollection')
Resources for the views are set in Generic.xaml file that is in subfolder Themes. I can not understand why it breaks and why those properties could not be found.
Here are also two examples. One is without MahApps.Metro reference. Another is with MahApps.Metro referenced and where ListView functionality breaks up.
Ok application, without MahApps.Metro and that shows proper ListView in WrapPanel, no errors:
WpfApp11-Ok.7z
Application with MahApps.Metro and that shows broken ListView, errors and no more WrapPanel:
WpfApp11-MahappsEnabled.7z
Here are both applications for reference:
https://filebin.net/qooty5o674obw29h

Binding Errors
The binding errors while debugging originate from the MahApps default style for ListView. As you can see in the MahApps.Styles.ListView style, the control template contains a ScrollViewer
that references a style called MahApps.Styles.ScrollViewer.GridView. This style is specific to a GridView and contains bindings to all the properties that are not found at runtime in the GridViewHeaderRowPresenter.
In other words, the default style for ListView in MahApps expects a GridView. In order to fix this, you will have to create a custom MahApps.Styles.ListView style to support your TileView.
Wrap Panel
The WrapPanel is applied in your application, but not when using MahApps. It seems that actually a VirtualizingStackPanel is applied. The MahApps default style for ListBox contains this Trigger:
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="True">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True"
IsVirtualizing="True"
IsVirtualizingWhenGrouping="True"
VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
It overrides your items panel (WrapPanel) that you set in your style which is based on this ListBox style. You can add this trigger to the style in your original application to produce the same result.
There are multiple options to solve this issue:
Create a copy of the base style and remove or change the trigger.
Create the same trigger in your style, but override the value with your items panel template
Add a setter in your style that sets the VirtualizingStackPanel.IsVirtualizing property to False.
Unfortunately these options do not work in the MahApps application. At the moment I cannot tell if it is related to other styles or the GridView issue above, but you can try if this works for you.

Related

Ribbon binding failures when used within a regular Window (not a RibbonWindow)

I'm using a Ribbon control from RibbonControlLibrary for .net 3.5.
I can't use RibbonWindow for some presentation-compatibility issues. So I place a Ribbon control inside Window.
There are no visible issues, but I'm getting 2 error messages in my VisualStudio output window.
Those messages are:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'RelativeSource FindAncestor,
AncestorType='Microsoft.Windows.Controls.Ribbon.RibbonWindow',
AncestorLevel='1''. BindingExpression:Path=WindowState; DataItem=null;
target element is 'Ribbon' (Name=''); target property is 'NoTarget'
(type 'Object')
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'RelativeSource FindAncestor,
AncestorType='Microsoft.Windows.Controls.Ribbon.RibbonWindow',
AncestorLevel='1''. BindingExpression:Path=IsActive; DataItem=null;
target element is 'Ribbon' (Name=''); target property is 'NoTarget'
(type 'Object')
This can be reproduced just adding a Ribbon to a Window and running the application.
Is there a way to tell Ribbon not to try to bind anything exactly to RibbonWindow but for Window?
Since you said you can't use RibbonWindow (for some reason...), I am assuming you're doing something like
<Window x:Class="Yournamespace" ...>
<Ribbon>
</Ribbon>
</Window>
Your ancestor should be
AncestorType='System.Windows.Window' and not 'Microsoft.Windows.Controls.Ribbon.RibbonWindow'
You probably have:
<Window x:Class="yournamespace"
xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
...>
<r:Ribbon>
</r:Ribbon>
</Window>
To fix this just replace <Window> and </Window> with <r:RibbonWindow> and </r:RibbonWindow>
this fixed it for me

What do binding Error codes mean, and where can I find a list of them?

When I get a binding error in WPF, there is an error code that goes with it.
For example,
System.Windows.Data Error: 40 : BindingExpression path error:
'Product' property not found on 'object' ''ProductModel'
(HashCode=57788087)'. BindingExpression:Path=Product;
DataItem='ProductModel' (HashCode=57788087); target element is
'TextBox' (Name=''); target property is 'Text' (type 'String')
or
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'RelativeSource FindAncestor,
AncestorType='System.Windows.Controls.ItemsControl',
AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment;
DataItem=null; target element is 'MenuItem' (Name=''); target property
is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
What do these error codes represent, and where can I find a list of them?
I don't think you'll find an official source documentation anywhere, these appear to be messages and codes internal to WPF assemblies.
This won't be the single place to find all the possible errors but if you look at the source, you could look at the MS.Internal.TraceData class and you'll find your error messages and codes there. It looks like it was refactored since this answer was posted but you can find these in the generated AvTraceMessages.cs file.
For instance, TraceData.ClrReplaceItem() corresponds to error 40 and TraceData.NoSource() corresponds to error 4.
Fortunately we now have access to the resource file that was used to generate these messages which you can find here. It looks like the error codes might correspond to the index within this file.

Dummy FallbackValue for IEnumerable Asynchronous

I am trying to debug some of the databinding/performance issues in my MVVM program (Josh Smith based). There is a lot of concurrent loading of different lists and objects, so I've been using isAsync and some threading to improve performance and network bottlenecks.
However, I am noticing a lot of messages being output from ItemsSource bindings on the fallback values. For commands I created a dummy command which disables commands, and for most things I can bind to a known fallback primitive type. The issue seems to come when I bind an ItemsSource's fallback to {x:Null}.
Note: This is happening in many spots not just the chartingToolkit controls
A first chance exception of type 'System.NotSupportedException' occurred in PresentationFramework.dll
A first chance exception of type 'System.Xaml.XamlObjectWriterException' occurred in System.Xaml.dll
System.Windows.Data Information: 41 : BindingExpression path error: 'LineValueList' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=LineValueList; DataItem=null; target element is 'LineSeries' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=LineValueList; DataItem=null; target element is 'LineSeries' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=LineValueList; DataItem=null; target element is 'LineSeries' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
<chartingToolkit:LineSeries DependentValuePath="Value" IndependentValuePath="Key" ItemsSource="{Binding Path=LineValueList,IsAsync=True,FallbackValue={x:Null}}">
Questions I have:
Are these messages worrisome? A lot of my end users have older machines (and refuse to upgrade -.-) so I've been trying to maximize performance.
Is it safe to create dummy base types and reference them from App.xaml?
I datatemplate most of these lists, is that causing this?
Thanks in advance.
You can use a PriorityBinding to bind to dummy datasources while your real source is loading.
I hope this helps.

Many binding errors in visual studio with WPF application?

When I debug my app visual studio gives many binding errors like those in the example here:
Anybody know why this is happening? Also colleague of mine doesn't have those binding errors but has the same version as me.
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=PlanningCd; DataItem=null; target element is
'TextBlock' (Name='planningSchema'); target property is 'NoTarget'
(type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=PlanningCd; DataItem=null; target element is
'TextBlock' (Name='planningSchema'); target property is 'Text' (type
'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=Measurements; DataItem=null; target element is
'ItemsControl' (Name='MeasurementAndTimeControl'); target property is
'ItemsSource' (type 'IEnumerable')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=Foreground; DataItem=null; target element is
'ItemsControl' (Name='MeasurementAndTimeControl'); target property is
'Foreground' (type 'Brush')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=PlanningCd; DataItem=null; target element is
'TextBlock' (Name='planningSchema'); target property is 'NoTarget'
(type 'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=PlanningCd; DataItem=null; target element is
'TextBlock' (Name='planningSchema'); target property is 'Text' (type
'String')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=OtherParams; DataItem=null; target element is
'ItemsControl' (Name=''); target property is 'ItemsSource' (type
'IEnumerable')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=Foreground; DataItem=null; target element is
'ItemsControl' (Name=''); target property is 'Foreground' (type
'Brush')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=IsSelected; DataItem=null; target element is
'ContentPresenter' (Name=''); target property is 'NoTarget' (type
'Object')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=Foreground; DataItem=null; target element is
'Grid' (Name=''); target property is 'Foreground' (type 'Brush')
System.Windows.Data Information: 10 : Cannot retrieve value using the
binding and no valid fallback value exists; using default instead.
BindingExpression:Path=Measurements; DataItem=null; target element is
'ItemsControl' (Name='MeasurementAndTimeControl'); target property is
'ItemsSource' (type 'IEnumerable')
Looks like many of the errors are an an element named planningSchema. I would start with adding the following to that binding. You can also attach a converter that really does nothing but pass string to string (or date to date). Then you can debug in the converter (or you may find out it does not even get as far as the converted). It would nice if the debugger would work in the XAML.
PresentationTraceSources.TraceLevel="High
Also colleague of mine doesn't have those binding errors but has the same version as me.
Your colleague may have a number of things set up differently in his Visual Studio:
Look in Tools > Options > Debugging > Output Window > WPF Trace Settings.
Here you can set the level of debugging trace output (between Off and Verbose) and also set the subject matter of output, eg. Animation, Data Binding, etc.
As #Blam has mentioned, you can also change the level of trace output by using the PresentationTraceSources.TraceLevel attached property on your controls.
Further changes could be because you may have configured your PresentationTraceSources differently in your app.config (but only if you use separate config files).

How can I make UIElement support binding?

DependencyProperties on UIElements do not support databinding (you get something like:
"Cannot find governing
FrameworkElement..")
. If you try, you get an error because WPF can not resolve the DataContext. From what I know, you get binding support if you inherit FrameworkElement or Freezable, but In this case I can not simply change the base class. Is there any way to get the UIElement to support data binding?
I've tried to add the DataContext property to the UIElement class like this:
FrameworkElement.DataContextProperty.AddOwner(typeof(Bitmap), new
FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
I also tried to bind by specifying "ElementName" in the binding expression, but I am still unable to resolve the parent DataContext (I thought that binding explicitly by ElementName would simply remove the need to resolve the DataContext).
This is the binding. The class in question is called "Bitmap".
<Utils:Bitmap Source="{Binding Path=Icon}" />
<TextBlock Grid.Row="1" Grid.ColumnSpan="3" MaxWidth="90" Text="{Binding Path=Name}" TextWrapping="Wrap" TextAlignment="Center"/>
The textblock binding works as expected, the first binding does not. The bound viewmodel has both properties (I bound to the Image class before and it worked).
The bitmap class can be found at this blog: http://blogs.msdn.com/b/dwayneneed/archive/2007/10/05/blurry-bitmaps.aspx
With some extended binding diagnostics, I get this output:
System.Windows.Data Warning: 65 : BindingExpression (hash=14926099): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=117163); target property is 'Source' (type 'BitmapSource')
System.Windows.Data Warning: 63 : BindingExpression (hash=6195855): Resolving source (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=6195855): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=55762700); target property is 'Source' (type 'BitmapSource')
System.Windows.Data Warning: 63 : BindingExpression (hash=48657561): Resolving source (last chance)
System.Windows.Data Warning: 65 : BindingExpression (hash=48657561): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Icon; DataItem=null; target element is 'Bitmap' (HashCode=35264868); target property is 'Source' (type 'BitmapSource')
You have to inherit FrameworkElement to use data binding. If you cannot change the base class, the only option you have is, as H.B. said, create an adapter that will be derived from FrameworkElement and will delegate all the functionality to an instance of the existing class derived from UIElement.
See http://msdn.microsoft.com/en-us/library/ms743618.aspx for more information on what the base framework classes (like UIElement and FrameworkElement) provide.
Update:
Even though MSDN (link above) says that the data binding support is introduced on the FrameworkElement level, it IS possible to set binding on any DependencyObject. The only thing is that in this case you cannot use DataContext as an implicit source for the binding and you cannot use ElementName for referring to the source.
What you can do is to set binding programmatically and specify source explicitly:
BindingOperations.SetBinding(MyBitmap, Bitmap.IconProperty, new Binding() { Source = this.DataContext /* Or any other source */, Path = new PropertyPath("Icon")});
OR you can use a little trick and use RelativeSource for referring to an element in the visual tree (in this case any parent FrameworkElement):
<Utils:Bitmap Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type FrameworkElement}}, Path=DataContext.Icon}" />
You can use {Binding Source={x:Reference elementName}} instead of {Binding ElementName=elementName}.
As noted you can bind on any object which inherits from DependencyObject, if you want a DataContext, I'd suggest you just make the class inherit from FrameworkElement. Even shapes like Rectangle do so, if you have some image-control it only makes sense to choose a higher level as the base-class.

Resources