I recently used a TranslateTransform in my WPF application to implement dragging a UserControl across the screen. There is a new bug in that after the first time you drag it somewhere else on the screen, when you click on the "Title bar" on the control, it jumps back to where it was originally displayed. It will still follow the mouse, but that initial jump is disconcerting.
I don't know what's going on, but this got me to wondering. Since WPF controls don't have a left or top property of their own, unless you put them into a Canvas, and those are attached properties anyway, just what properties are being modified by the TranslateTransform?
WPF's layout and render passes have intrinsic knowledge of transforms. By modifying the X and Y properties of the TranslateTransform, you're causing the layout/render pass to take those new values into consideration when positioning the associated FrameworkElement.
To put it another way: the TranslateTransform is not modifying other properties, but by modifying its properties you are triggering another layout/render pass and thus affecting the on-screen positioning of the associated FrameworkElement.
Read here for more information.
Related
I'm making a custom dropdown button (since the one included in wpf requires too much hacking to style right). Now that i got the button bit out of the way i need to add the drop down part.
My first thought was to add a stackpanel and use that to contain the items but it gets cut off if it leaves the borders of the grid that the button is in. Next up was the popup primitive, it gets on top of everything nicely enough but position wise it just free floats and i haven't figured out how to make it follow the button it was spawned by. I also tried using contextmenu but that seems to have no positioning controls at all and just sits where the mouse made it..
Anyways wpf is a big package and I'm just getting into it, anybody know which direction i might find what I'm looking for?
Preferred approach normally is to use a Popup. You got two very important properties with a Popup
PlacementTarget and Placement
Setup a binding for PlacementTarget on the Popup to your custom Button and then use Placement to position the Popup accordingly w.r.t to the PlacementTarget(Button)
Placement accepts an enum of type PlacementMode which gives you quite a few options to position the Popup.
I am designing a code viewer using a virtualized ListView control to display code lines.
Now I want to create a highlight effect when the user clicks a link which takes them to a particular line. I want the target line to be highlighted.
The effect will be either an "underline" appearing (and disappearing) or a semi-transparent overlay (like a marker pen) appearing (and disappearing). The actual graphical effect itself is unimportant, that's not the problem.
What is the best approach to achieve this? I'm not quite sure where to start.
Some technical requirements might be that I need to:
find the right events to react to - or use databinding
obtain the absolute bounding rectangle of the virtualized target item (although when brought into view the item should be available)
absolutely position a canvas effect on top, fade in and fade out
...Ideally some state changes in a view model, a piece of XAML is animated via a triggered storyboard to appear (fade in) above the relevant ListViewItem and then animates away again (fade out). Of course before the fade in, the element must already be correctly positioned over the relevant ListViewItem...
I have worked on a search feature for a Listview where every ListViewItem had few textbocks. When the user types something in a search textbox, all the matches in the listview was supposed to get highlighted.
I created Run objects based on the search string (used Regex to find the match) and then set the Background to some color. Also, held the reference of the ListViewItem in the tag of the Run object which helped me to use call ScrollIntoView. Hope this will be of some help in your case.
All the documentation seems to suggest that setting the RenderTransform isn't supposed to impact arrange. But that's not exactly the behavior I'm seeing.
I have an odd requirement for a control layout. I wanted to leave as much of wpf's layout system as I could, so I created an element that inherits Decorator.I have an attached property that marks the elements I'm interested in.
During arrange, I call the base ArrangeOverride method, which layouts out the elements using the normal process. Next, I crawl through the controls with the attached attribute and, using the render transform, I re-position the controls where I want them.
All of this works fine, until I use an items control. Assigning the RenderTransform is causing the arrange to be invalidated and my arrange method is being called repeatedly. The documentation seems to suggest setting the RenderTransform has no impact on Arrange.
I have a control template defined, call it myVal, that is used for validation - this is then used for example in a Style targeting textbox where its Validation.ErrorTemplate is set as
Now say there are a number of such textboxes that sit in a view and that this slides in using TranslateTransform and BeginAnimation.
The result is that the adorner used in the ErrorTemplate doesn't follow the position of the textboxes as the view transitions - instead these stay in the starting position. However, the adorners reposition themselves correctly in relation to the textboxes as soon as I set focus or events such as mouse move.
How can I get the adorners to show in the correct position after the transformation without having to change the focus? Is there a way of delaying the validation until after the transition...or how can I "revalidate" the properties once the animation has finished? I read somewhere about calling invalidatevisual but can't see how I'd do that. Any help is much appreciated.
Cheers
Two ideas:
Try adding an AdornerDecorator around the textbox, or around the group of textboxes. This will tell WPF to add another layer for rending adorners. Adding a layer "closer" to the textboxes might help.
If you want to tell the adorner layer to re-render itself, then you can use something like the following code:
var al = AdornerLayer.GetAdornerLayer(myTextBox);
al.Update();
I have an ItemsControl with a number of elements, each one with its own ViewModel instance. Each item's ViewModel knows whether that item should be visible (currently each ViewModel has a Visibility property that the UI binds to). When my window first opens, some of these items are visible, others are collapsed. Later, some items' visibility might change in response to user interaction. The window sizes to its content, so the window resizes when items are shown or hidden. And the window is initially centered on the screen (which means everything has to be arranged properly right away, so the window knows its initial size and can center itself accordingly).
Now I want to add animations whenever an item is shown or hidden -- but I only want to animate if the item's visibility changes after the window is already shown. So if the window is already open, and the user does something that makes one of the ViewModels want to appear, it animates in; if the user does something to make one of the ViewModels disappear, it animates out. But when the window first opens, I want everything to start out rock-solid -- no lingering animations.
And I want the window to still set its initial size based on its initially-visible content, and I still want it to be initially centered onscreen. (Although actually, in this case, it would be acceptable if it centered itself as if all items were visible, if event ordering made it work out that way.)
I know a fair bit about WPF, but I admit I'm lost when it comes to triggers and storyboards. I haven't really done anything with WPF animations before, and I'm not sure where to begin.
I already tried using Reveal from the Bag of Tricks, but I had several problems with it, the biggest being that it doesn't have the "only use animations after the window is shown" behavior that I want -- my window would appear and the initially-visible elements would still be animating in. It also didn't play well with my layout (it was centering the elements horizontally, instead of stretching them to the ItemsControl's width), and a few other problems that might or might not be fixable.
I'm not too picky about whether I animate by stretching (e.g. by animating a LayoutTransform from SizeX=1 SizeY=0 to SizeX=1 SizeY=1, thus starting with squished text and expanding to normal size) or by just changing the Height (thus starting with only part of the content visible and revealing more as the animation progresses) -- I'm fine with either.
I'm open to writing my own Panel descendant (I've done it before) if that's the best way to solve this, and I can always steal code from Reveal and hack until I get it working -- but it seems like there should already be an easier way to do this, if I just knew what it was. I'm open to learning about triggers and storyboards, or whatever, if someone can point me in the right direction.