I have a control which allows the user to add and manipulate n graphical and text layers. The layers are each usercontrols that are added to the parent control's canvas. I use the parent control's LayoutUpdated event to refresh transform specific variables and other stuff. With no change to the handler method, the LayoutUpdate event stopped firing. I've obviously done something that caused it, but I haven't been tinkering with anything that can logically tie to this new problem. Any ideas are appreciated - thanks.
JUST TO CLARIFY: I'm not asking for a solution - just an anecdote of experience with something similar - That will probably be more helpful than you can imagine. Thanks
The cause, in this case, was a WPF UserControl (kid) defined in xaml at design time inside a canvas without any dependency property values set. The canvas is inside another usercontrol of different type (mom). At runtime, a mom is instantiated and her kid is sized, positioned, and made visible within the canvas of mom based on the runtime size of mom as well as calling arguments that denote whether or not kid is to be visible. This instance of kid is only sized and positioned if it is requested to be visible, if not, it is only hidden (not sized, not positioned).
The presence of this instantiated, but unsized and unpositioned element within the canvas of mom was causing the failure of layoutupdated events to fire. This situation effected not only the instance in question, but all other instances created at runtime in the project afterward. (NOTE - no exception was raised)
The solution appropriate for this circumstance was to explicitly size and place this element within the canvas - even if it is not needed. The layoutupdated events then fire as expected. I would love to provide a more profound and generalized answer, but perhaps wiser people can include their insight as well. Thanks
Related
Currently I am stuck with a problem that is simple on the first sight. Its about automated GUI testing.
I want to make a row/cell of a WPF DatGrid completely visible by scrolling using ScrollIntoView(row) and then accessing the row/cell directly after. Unfortunately scrolling in ScrollViewer seems to happen asynchronously. This means I need to wait for the scrolling to finish before accessing the row/cell. For this purpose I found the ScrollChanged event I can subscribe.
There is only one detail I can not solve: If the row/cell I want to access is already visible (and no scrolling is necessary) I do not get that event and the algorithm gets stuck. I was not able to find a reliable way to predict if a call to ScrollIntoView(row) actually scrolls.
Any idea how to solve this?
To make sure layout is updated call UIElement.UpdateLayout after you ScrollIntoView and before you want to use item. Quoting MSDN it
Ensures that all visual child elements of this element are properly updated for layout.
Here is a problem: after loading some visual elements, I need to change something knowing their new sizes. There is MeasureOverride method, but it is called before changing the size. Is there any method that is called after it?
P.S. I know that I can calculate new sizes having old ones, but new sizes aren't calculated simply. It would be much easier to just use such an event (if it exists).
Are you looking for the FrameworkElement.SizeChanged event?
MSDN's description:
Occurs when either the ActualHeight or the ActualWidth properties change value on a FrameworkElement.
EDIT:
This article has a good description of both the SizeChanged and LayoutUpdated events, including an overview of how the layout loop works.
Good afternoon. I'm creating a custom WPF layout control that needs to omit children from the measure/arrange process if they won't fit in the available area. I'm testing with Blend.
I have tried overriding GetVisualChild(n) and VisualChildCount to try and allow the runtime to only recognize certain elements as my desired children. This seems to work okay, but the big issue I'm having is this:
I drop some children into my layout control from Blend. I then shrink the control where some children won't fit inside my panel. The issue is that the children that are no longer in view remain rendered on the Blend design surface. I have tried invalidating their visual, calling "RemoveVisualChildI()".. but nothing seems to want to make the rendered visuals disappear.
Breaking into the GetViasualChild(...) method, I am witnessing Blend and the runtime are only asking for the actual visible children (fully contained inside my layout panel). So, it seems to me that the problem is tied to the child elements thinking that they still need to be rendered..or that the container panel just doesn't know it needs re-rendering.
Any clues? I can try and provide more detail if it's needed, but my basic need is the ability to selectively hide/show (omit from the measure/arrange process) certain children of a custom panel.
Thanks!
- Sean
Since nobody has responded, I figured I would share the solution. The visual tree is established through the AddVisualChild(...) method on the Visual base class. The Panel takes care of this for you with it's Children collection. To solve this, all I needed to do was create an instance of a UIElementCollection, and let it do the dirty work. When that class is created, it is passed a visual parent and an optional logical parent. When elements are added to that collection, the parent / child relationship gets established automatically.
Hope this helps the next person!
A WPF window should have hundreds of objects (rows of rectangles) and mouse clicking on each of them should fire similar actions. These actions differ only by several parameters (say "No. of Row" and "No. of position in a row").
Should I have hundreds of almost the same event handlers or how I could optimize my code?
Please give me some tips, just to move to the right direction.
Best regards.
WPF mitigates this problem by introducing Routed Events. At any level in the element hierarchy you may intercept events from its child elements and base your logic depending on the actual element that received this event in the first place (as presented by the Source property of RoutedEventArgs).
I'm no expert in WPF, but in event handling you could write 1 dans point every similar event to this handler. In the handler use the senter parameter to know whish control it came from.
Instead of 100's of similar event hander you could have a big one with a switch
Hope that's help
Can't you just use an instance of ICommand on your viewmodel and use the command parameter to determine which rectangle was clicked?
Scenario: I have a (numeric) textbox, a button, and a label. When the button is clicked I'd like the label to "animate" to the numeric value in the textbox (like a spinning dial)
Given:
a) that animations in storyboards cannot have databindings (because they are not FrameworkElements)
b) the lack of triggers in Silverlight
What is the best, and with least coupling of the view model to the view's storyboard, way to update the target animation value and start the animation when the button is clicked?
Note: The scenario is conceptual, so don't concentrate on the specifics of 'animating' numbers or anything
If your goal is strictly to reduce the code-behind in the view I think that an attached behaviour on the Label would work for this. The attached behaviour on the label would expose the number to be animated to and when this number changes an animation (in code) would be run to animate from the old value to the new value.
One drawback is that your animation is now in code, unless you store a templated (just has fake values to start with) version of it in a resource file somewhere where you can load it as needed and replace the templated values.
This article from Josh Smith seems to be the authority on Attached Behaviours;
http://joshsmithonwpf.wordpress.com/2008/08/30/introduction-to-attached-behaviors/
I recently had to solve a similar problem in an MVVM application. My problem was that I needed to animate a container's height from zero to auto. Since Auto is a dynamic value I recognized that the animation (or storyboard) would need to be built (or manipulated) on demand. The solution that I put in place involved using view code-behind to update and fire the animation.
This isn't the most MVVM-friendly approach; however, animations in WPF can be tricky in XAML. Since this solution is really just a workaround for a XAML limitation it seems okay to tie the code directly to the view. Likewise, if the views were mocked then there would be no framework elements to animate, so it really wouldn't make sense to place this code on the VM side.
Does anybody have a better approach?