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

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

Related

ListView custom view binding errors when MahApps.Metro referenced

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.

How to find the binding triggering a System.Windows.Data Error 4 in the debug logs

I've one big WPF application, at some point we create a lot of objects(and a lot of GUI are bound to the newly selected object with a lot of subcontrols.
This generate a bunch of binding error, of 2 types:
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 'ListBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ListBoxItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')
(each error is displayed ~10-20 times).
I've looked for solution prior to asking but:
If I use snoop to see the part of GUI that triggers error, I don't get errors anymore
Looking for parts of errors. I've double-checked, but we bind nowhere VerticalContentAlignement or its horizontal counterparts, it's always bound to a given value
I cannot find the binding that would be missing(and maybe it's one of those temporary state)
I'm kind of lost, I don't see how I can debug this? We were having a lot of binding errors in the past and now we want to have none, in order to easily see if there is an issue with something we are developing.

WPF binding at runtime not working

Using .NET 4.7.1 WPF with MahApps 1.6.1.4. I'm binding the HamburgerMenuIconItem.Icon like this:
<controls:HamburgerMenuIconItem.Icon>
<Ellipse">
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding Image}" />
</Ellipse.Fill>
</Ellipse>
</controls:HamburgerMenuIconItem.Icon>
In Design mode I can right click "Image" and go to the property in my ViewModel that is the UserControl.DataContext. As expected.
But in runtime this fails with this error:
System.Windows.Data Error: 40 : BindingExpression path error: 'Image' property not found on 'object' ''HamburgerMenuIconItem' (HashCode=44346036)'. BindingExpression:Path=Image; DataItem='HamburgerMenuIconItem' (HashCode=44346036); target element is 'ImageBrush' (HashCode=21345065); target property is 'ImageSource' (type 'ImageSource')
So at runtime it is trying to bind to a property in the "HamburgerMenuIconItem" or what? I can force the binding to the View code behind like this:
{Binding Path=Image, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}
Which works at runtime also, but I'd like the property in my ViewModel.
What am I misunderstanding?
Seems the issue is missing inheritance of the DataContext (but only at Runtime). The solution explained here solved my issue.

WPF Binding to Window property failing

I've got a custom control class in my project called "CarSystemWindow". It descends from Window and has a custom template that gives all windows in my application the same look. It also defines two dependency properties named DeviceName and DeviceType. These are of type string. They default to "Vehicle: " and "Car 54", respectively.
In my main program, I retrieve a row from my database into a View Model object and save that in a normal CLR property called Site during the program's initialization. In the MainWindow's xaml, I have the following code:
<cs:CarSystemWindow x:Class="....MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:..."
xmlns:cs="..."
Background="Black"
Closed="Window_Closed"
DataContext="{Binding Path=Site, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
DeviceName="{Binding Path=SiteName}"
DeviceType="{Binding Path=SiteTypeName}"
Icon="..."
Height="600"
Loaded="Window_Loaded"
ResizeMode="CanMinimize"
SourceInitialized="Window_SourceInitialized"
Title="Window Title"
Width="800"
WindowStartupLocation="CenterScreen">
At run time, the binding on the DataContext attribute is failing with the following message:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=Site; DataItem=null; target element is 'MainWindow' (Name=''); target property is 'DataContext' (type 'Object')
I'm using this same binding code elsewhere and it works. I've even turned the Site property into a dependency property and its still failing.
Does anyone give have ideas why the binding is failing?
Thanks
Tony
I think you need to change your binding to this:
{Binding RelativeSource={RelativeSource Self}, Path=Site}
The reason your current binding is not working is that you are trying to go up a level in the hierarchy from the Window, but you actually want the Window.
Here is a good source for figuring out what the binding string should be for different scenarios:
http://www.nbdtech.com/Free/WpfBinding.pdf
The problem with the DataContext binding is that the line is saying to use the Site property on an object that is an ancestor of this object, and of type Window. Since this object is a Window already, and therefore at the root of the visual tree, there are no ancestors to search and find the specified property.
Why don't you assign the DataContext where this object is constructed?

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