I am encountering a situation in which WPF successfully creates an Image element on one of my views but appears to take a second or two to properly set up the logical parent of that element. If I mouse over in that time window, my application crashes due to an ArgumentNullException from the LogicalTreeHelper.
If I wait for the second or so, everything works fine and there are no problems. But I can hardly ask my users to do that.
Note that this only happens when my UserControl, is housed in FixedPage in a FixedDocument shown by a DocumentViewer. When I use the same control in other contexts, (away from FixedDocument et al), it works without issue.
Does anyone know anything about this "window" or what might be the cause of it?
This is the code in FixedPage.cs that's trying to get the parent of my item. I've added comments.
internal int[] _CreateChildIndex(DependencyObject e)
{
ArrayList childPath = new ArrayList();
while (e != this)
{
// *** 'e' is an Image control, created by my view ***
// *** This value 'parent' is NULL if I mouse over too quickly ***
DependencyObject parent = LogicalTreeHelper.GetParent(e);
int childIndex = -1;
if (parent is FixedPage)
{
childIndex = ((FixedPage)parent).Children.IndexOf((UIElement)e);
}
else if (parent is Canvas)
{
childIndex = ((Canvas)parent).Children.IndexOf((UIElement)e);
}
else
{
// *** Because 'parent' is null, we end up here. This call throws ***
IEnumerable currentChildrens = LogicalTreeHelper.GetChildren(parent);
Here is the code that throws
public static IEnumerable GetChildren(DependencyObject current)
{
if (current == null)
{
throw new ArgumentNullException("current");
}
This is the call stack from the mouseover. None of my code in here except the App.Run method.
System.Windows.LogicalTreeHelper.GetChildren C#
System.Windows.Documents.FixedPage._CreateChildIndex C#
System.Windows.Documents.FixedTextView.GetTextPositionFromPoint C#
MS.Internal.Documents.TextViewBase.System.Windows.Documents.ITextView.GetTextPositionFromPoint C#
MS.Internal.Documents.DocumentPageTextView.GetTextPositionFromPoint C#
MS.Internal.Documents.MultiPageTextView.GetTextPositionFromPoint C#
MS.Internal.Documents.TextViewBase.System.Windows.Documents.ITextView.GetTextPositionFromPoint C#
System.Windows.Documents.TextEditorMouse.IsPointWithinInteractiveArea C#
System.Windows.Documents.TextEditorMouse.OnQueryCursor C#
System.Windows.RoutedEventArgs.InvokeHandler C#
System.Windows.EventRoute.InvokeHandlersImpl C#
System.Windows.UIElement.RaiseEventImpl C#
System.Windows.UIElement.RaiseTrustedEvent C#
System.Windows.Input.InputManager.ProcessStagingArea C#
System.Windows.Input.MouseDevice.UpdateCursorPrivate C#
System.Windows.Input.MouseDevice.PostProcessInput C#
System.Windows.Input.InputManager.RaiseProcessInputEventHandlers C#
System.Windows.Input.InputManager.ProcessStagingArea C#
System.Windows.Input.InputProviderSite.ReportInput C#
System.Windows.Interop.HwndMouseInputProvider.ReportInput C#
System.Windows.Interop.HwndMouseInputProvider.FilterMessage C#
System.Windows.Interop.HwndSource.InputFilterMessage C#
MS.Win32.HwndWrapper.WndProc C#
MS.Win32.HwndSubclass.DispatcherCallbackOperation C#
System.Windows.Threading.ExceptionWrapper.InternalRealCall C#
System.Windows.Threading.ExceptionWrapper.TryCatchWhen C#
System.Windows.Threading.Dispatcher.LegacyInvokeImpl C#
MS.Win32.HwndSubclass.SubclassWndProc C#
[Native to Managed Transition]
UserCallWinProcCheckWow Unknown
DispatchMessageWorker Unknown
[Managed to Native Transition]
System.Windows.Threading.Dispatcher.PushFrameImpl C#
System.Windows.Threading.Dispatcher.PushFrame C#
System.Windows.Threading.Dispatcher.Run C#
System.Windows.Application.RunDispatcher C#
System.Windows.Application.RunInternal C#
System.Windows.Application.Run C#
MyCompany.App.Main Unknown
[Native to Managed Transition]
coreclr_t::execute_assembly C++
run_app_for_context C++
run_app C++
corehost_main C++
execute_app C++
`anonymous namespace'::read_config_and_execute C++
fx_muxer_t::handle_exec_host_command C++
fx_muxer_t::execute C++
hostfxr_main_startupinfo C++
exe_start C++
wmain C++
[Inline Frame] invoke_main C++
__scrt_common_main_seh C++
BaseThreadInitThunk() Unknown
RtlUserThreadStart() Unknown
Below is a very much abbreviated version of my view (a UserControl) with the ItemsControl that creates the Image element
<UserControl
x:Class="Core.Views.LayerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:cv="clr-namespace:Core.View"
>
<Canvas>
<ItemsControl ItemsSource="MyItems">
<ItemsControl.Resources>
<DataTemplate x:Key="PathOutputTemplate" DataType="{x:Type ShapeVm}">
<Path Stroke="Yellow" StrokeThickness="6" Data={Binding Geometry} />
</DataTemplate>
<DataTemplate x:Key="ImageOutputTemplate" DataType={x:Type ImageOutputVm}>
<Image Source="{Binding ImageSource}"/>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemTemplateSelector>
<cv:OutputTemplateSelector
PathTemplate="{StaticResource PathOutputTemplate}"
ImageTemplate="{StaticResource ImageOutputTemplate}"
/>
</ItemsControl.ItemTemplateSelector>
</ItemsControl>
</Canvas>
</UserControl>
I encountered this problem today when creating a new report and wanted to post my workaround for any future developer that hits this issue. This is really a workaround and not a fix for the underlying issue as I didn't have time to dig deeper.
The workaround consisted of adding a Border control with Transparent background over my image controls, essentially preventing any mouse events from triggering below:
<Grid>
<My-content-that-must-not-be-moused-over/>
<Border Background="Transparent"></Border>
<Grid>
Related
Preamble: I have to design components that work with Visual Studio WPF Designer to create custom applications. For example a Line User Control.
Scenario
In Blend 2012, if you draw a line on the Designer Surface, the editor creates something like
<Path Data="M5.5,5.5 L502.5,308.5" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="304" Margin="5.5,5.5,0,0" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" Width="498"/>
in the .xaml behind code at Design Time, even if you can expect something like
<BlendLineControl ... />
like every noraml WPF User Control.
The Problem
I need to create a similar control in Visual Studio with which the user can draw a line on the Designer Surface and when the draw ends the control adds a Path to the .xaml behind, instead of
<myControls:myLineControl ... />
Is there a way to achieve this result?
#Riccardo, your question description is very poor and that is why you still haven't received any proper answers, even after 17 hours. This is not a criticism, but advice instead. If you carefully think about what you want and how best to put it into words before you ask your question, you will probably get better and quicker answers.
Only after reading your comments, was I able to guess what you actually wanted, as that was not at all clear from your question. In your comment, you said
I HAVE TO design components that work with VS WPF Designer to create custom applications
I have no idea why you wouldn't put crucial information like that into your question, but now that I know that, I can suggest a possible solution for you. Of course, that's still not a very clear description, so this might not be what you're after, but I think that you are looking for some way to extend the functionality of the Visual Studio WPF Designer.
If that is the case, then please see the WPF Designer Extensibility pages on MSDN. They will show you how to add custom editors, or Adorners into the Visual Studio WPF Designer and describe how to implement custom design-time logic, among other things.
If this is not what you are after, then I have no clue what you do want and suggest that you seriously improve the clarity of your question.
hello you should register a dependency property. and then implement how to interpret the value that would be passed to you
as an example, i have this small user control
<UserControl x:Class="Gnl.FxWinModule.ViewViewModel.LegView">
<Grid>
<dxlc:LayoutGroup x:Name="LegLayoutGroup"
View="GroupBox"
Grid.Column="0>
</dxlc:LayoutGroup>
</Grid>
</UserControl> and i would like to put it in a parentWindow and i want my layout group to have a different header name. so i declare a dependency property like this
public static readonly DependencyProperty LegNameProperty = DependencyProperty.Register("LegName", typeof(string), typeof(LegView), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender, OnLegNameChanged));
public string LegName
{
get { return (string)GetValue(LegNameProperty); }
set { SetValue(LegNameProperty, value); }
}
private static void OnLegNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var legControl = (LegView)sender;
legControl.LegLayoutGroup.Header = (string)e.NewValue;
}
public string GetViewName()
{
return string.Empty;
}
i'm now able to declare the following in my parent windows <VM:LegView Grid.Column="0" LegName="Buy Leg"/> hope it helps you
Im new to programming and in need clarification for the following ...
I have a text box in which text is automatically generated .
Requirement: If i now highlight the text in the text box a new wpf window should open ..
(this needs to be done using either wpf commands on attached property only/ not events)
Thanks :)
P.s please give me detailed code for a reply ..
This is a very strange requirement but it can be done using behaviors. Here is some sample markup:
<Grid>
<TextBox Text="This is some text">
<i:Interaction.Behaviors>
<local:NewWindowOnSelectBehavior/>
</i:Interaction.Behaviors>
</TextBox>
</Grid>
and here is the behavior that for demonstration purposes shows a message box:
public class NewWindowOnSelectBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
AssociatedObject.SelectionChanged += (s, e) =>
{
if (!string.IsNullOrEmpty(AssociatedObject.SelectedText))
MessageBox.Show("New Window");
};
}
}
This example uses behaviors. If you are not familiar with behaviors, install the Expression Blend 4 SDK and add this namespace:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
and add System.Windows.Interactivity to your project.
I've just installed IronPython 2.7 with VS support, and am trying to create a simple prototype WPF application. Something is broken, probably in my installation, and I can't figure out how to diagnose it. I can't get the simplest of bindings to work; they fail with an exception that seems really, really wrong.
I create a WPF application project, and put XAML like this in my WpfApplication1.xaml file:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1">
<Grid>
<TextBox x:Name="MyTextBox" Text="{Binding RelativeSource={RelativeSource Self}, Mode=OneWay, Path=ActualWidth}"/>
</Grid>
</Window>
When I run this, I get this exception:
System.Xaml.XamlObjectWriterException was unhandled by user code
Message=Provide value on 'System.Windows.Data.Binding' threw an exception.
InnerException: System.Windows.Markup.XamlParseException
Message=A 'Binding' cannot be set on the 'Text' property of type 'TextBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Hmm, last time I looked, Text is a dependency property. And indeed, if I create the binding in code, it works:
import clr
clr.AddReference('PresentationFramework')
from System.Windows import Application, Window, Controls, Data, PropertyPath
class MyWindow(Window):
def __init__(self):
clr.LoadComponent('WpfApplication1.xaml', self)
t = self.FindName("MyTextBox")
b = Data.Binding()
b.RelativeSource = Data.RelativeSource.Self
b.Mode = Data.BindingMode.OneWay
b.Path=PropertyPath("ActualWidth")
t.SetBinding(Controls.TextBox.TextProperty, b)
I'm pretty baffled at this point. It's hard for me to imagine anything that could cause this problem that wouldn't also mess up creating WPF objects from XAML completely. Is there something obvious that I'm missing?
This is a bug in the new WPF support. It's fixed in the current sources and so it will be fixed in the Beta 1 release. The underlying cause is that there are "schema contexts" which need to be used to get full WPF semantics that we weren't using before. It also moves to a new "wpf" module instead of being in the clr module.
I have implemented a few custom behaviors and triggers and added them via XAML. They work fine at run time but prevent the Cider designer view from loading at design time, and presumably will cause a problem in Blend too, though I haven't confirmed that.
Here is an overview of what I've implemented for one of the behaviors; hopefully someone can point out what I'm missing.
The behavior looks like this;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Interactivity;
namespace MiX.Core.UI.Silverlight
{
public class UpdateOnTextChangedBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged += OnAssociatedObjectTextChanged;
}
void OnAssociatedObjectTextChanged(object sender, TextChangedEventArgs e)
{
BindingExpression binding = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -= OnAssociatedObjectTextChanged;
}
}
}
An implementation in XAML looks like this;
<TextBox x:Name="Username" Text="{Binding Username,Mode=TwoWay}" BorderThickness="1" Style="{StaticResource TextBoxStyleGeneral}" Foreground="#FF333333" FontSize="10" BorderBrush="{x:Null}" Grid.Column="1" d:LayoutOverrides="GridBox" Margin="2,0" Grid.ColumnSpan="2" Background="{x:Null}" VerticalAlignment="Center" Grid.Row="1">
<i:Interaction.Behaviors>
<mixcore:UpdateOnTextChangedBehavior/>
</i:Interaction.Behaviors>
</TextBox>
In the XAML editor the <mixcore:UpdateOnPasswordChangedBehavior/> element is highlighted with a squiggly and reports the error A value of type 'UpdateOnTextChangedBehavior' cannot be added to a collection or dictionary of type 'BehaviorCollection'. When attempting to view in the Design view the designer fails to load, stating The document contains errors that must be fixed before the designer can be loaded.
In Silverlight ,If design is not able to load with the changes we made in code then it is bug in silverlight.
Silverlight yet is not designed to handle various exceptions through code,like if you do have any code with return type and you don't check for null there,then again it doesn't load the designer this case is mostly seen with Overriding the IValueConverter method {x:Static} ...and so on
There is nothing wrong in your code unless until it compile fine and doesn't throw exception.
Don't worry about the designer.
Similarly,one case you can look at:
http://connect.microsoft.com/VisualStudio/feedback/details/361509/xaml-designer-cannot-handle-typename-with-nested-classes
I've noticed that if you have anything deriving from UIElement as items in a ListBox in Silverlight it renders the object as is and isn't paying any attention to settings of DisplayMemberPath and/or ListBox.ItemTemplate.
For example if you have XAML like this:
<ListBox Width="200" Height="300" DisplayMemberPath="Tag">
<TextBlock Tag="tag1">text1</TextBlock>
<TextBlock Tag="tag2">text2</TextBlock>
<TextBlock Tag="tag3">text3</TextBlock>
</ListBox>
In Siverlight this produces a ListBox with items like this:
text1
text2
text3
However in WPF (and I think this is correct behavior) it lists tags as expected:
tag1
tag2
tag3
If I use objects that aren't inherited from UIElement everything works as expected:
<ListBox Width="200" Height="300" DisplayMemberPath="[0]">
<sys:String>abcde</sys:String>
<sys:String>fgh</sys:String>
</ListBox>
Produces:
a
f
Is there any way to use UIElements as ItemsSource in Silverlight the same way as any other objects? Or am I missing something?
It looks like the issue is in the PrepareContainerForItemOverride method in ItemsControlBase class. If you look at that method in reflector you will see that if the item is a UIElement then the logic to populate the items using the DisplayMemberPath doesn't get called.
If you want to get the behavior you are after you would need to subclass the ListBox control and override this method and set the values you want set on the ListBoxItems.
Here is an example:
public class MyListBox : ListBox
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
if (!object.ReferenceEquals(element, item))
{
ContentControl control = element as ContentControl;
if (control == null || this.ItemTemplate == null)
{
return;
}
control.Content = item;
control.ContentTemplate = this.ItemTemplate;
}
}
}
And you need to have an ItemTemplate for this to work. The DisplayMemberPath property is a little more complicated to implement.
<local:MyListBox Width="200" Height="300" DisplayMemberPath="Tag">
<local:MyListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Tag}" />
</DataTemplate>
</local:MyListBox.ItemTemplate>
<TextBlock Tag="tag1">text1</TextBlock>
<TextBlock Tag="tag2">text2</TextBlock>
<TextBlock Tag="tag3">text3</TextBlock>
</local:MyListBox>
Don't forget to add the xmlns for the local and set it to your assembly that implements the control.
Good luck!
Silverlight and WPF both are differently coded by microsoft, for example yet lot of functionalities of dependency properties are still missing in silverlight 3.0
Now looking at your code, simply means that DisplayMemberPath in silverlight isnt working correctly for dependency objects, but it works better for pure clr objects only for now. However they might come up with an update if you post bug at microsoft connect web site.
Dependency properties are still new in SL 3.0 so we hope to see some improvement in SL 4.0. If you use reflector, you will see that everything like stackpanel and all basic controls differe a lot in implementation in both places.