Bring control to view - wpf

Is there an easy/good way to bring control into view (make it visible on screen) ?
So far I have tried to do it manually by walking component trees and invoking relevant methods (BringIntoView) and properties (Visibility) but it is rather complicated due to multiplicity of base types (FrameworkElement vs FrameworkContentElement, there is also Visual3D and maybe more?), parent relationships (visual, logical, template) and necessity of customized handling of certain types (e.g. TabItem.IsSelected, Expander.IsExpanded - and ideally that should not assume that control is inside Content). There are probably many edge cases that are not covered by this.
UPDATE
The code I'm using currently: https://gist.github.com/2761622

Related

Benefits of Custom WPF Controls

I've thoroughly checked the custom controls topic, spent several hours looking into custom controls written by other people. I've written my own custom button, to feel it better. I've read all the google answers around the "why custom controls", "advanced custom controls examples" and such.
My question is, WHY?
Why would I (or anybody) go through 9 circles of hell to create his own custom control, when one can just adjust an existing control to his needs (using styles and templates). I actually didn't find any explanation on google, just tons of examples, mostly from people who sound even less educated than me.
I imagine there IS such need, when talking about some complicated DataGrid with, I don't know, every cell being a button or something (and still I believe I could do it with a regular DataGrid)... But I've not found anything more complex than a beautiful button. Is there nobody sharing a complicated code on the topic?
There are different levels of element customization in WPF, depending what class you extend from. Each has its own uses and is implemented differently. It is not clear from your question if you are asking about a specific type of control or about all of them in general. So, I will tell you what I think about different ones.
UIElement or FrameworkElement
Extending UIElement gives you the lowest level custom control where you have complete control over the layout and rendering. FrameworkElement is slightly higher level as it does most of the common layout stuff for you while also allowing you to override key parts of it. The main idea with these is that they do their own rendering rather than composing other elements together.
I have made a number of custom FrameworkElements over the years. One example is a ruler similar to one you might find in a program like Photoshop. It has a bunch of properties providing customization for how it is displayed as well as showing markers indicating mouse position relative to the ruler (and a number of other little optional features). I have used it in two different professional projects. I think the main benefit is that it is extremely easy to drop in and set properties/bindings on wherever desired. Build it once, use it over and over.
Control
Extending Control introduces the concept of compositing multiple elements/controls into one reusable component via control templates.
I have used this one less often, but still find it very valuable in the right circumstances. Again, the main benefit here is reusability. You create a control with properties that make sense for what you want to do, then hook up those properties to the properties of the controls in it's control template. Really, this is the same as applying a new template to an existing control, with the added feature of being able to define your own dependency properties. You also have the ability to perform custom logic in the control's code if you need to.
I may be misreading some of your text, but you seem to imply that making a custom control is considerably more difficult than making a control template for an existing control. I have found that the two are nearly identical in most cases using this approach, the only difference being whether you have a code behind you can use.
User Control
A user control is really only slightly different from a custom control practically speaking. Only, instead of defining a control template, you define the visual content directly.
This is probably the most common type of custom control. It is basically the standard method for making XAML based content in a WPF application. These can be reused like other controls, but are more suited for single use such as the content of a dialog or window or something else that is specific to a single application.
Some Other Control
You can also extend an existing control to add additional functionality to it. This way, you still get all the features the control offers and only have to implement the additional bit.
For example, I have a custom control called an AutoScrollRichTextBox that extends RichTextBox. So, it does everything a RichTextBox can do. It also has the ability to automatically scroll to the bottom when content is added to the text box (which it only does if the text box was already scrolled to the bottom before the addition content was added).
I could have implemented that feature as an attached property instead of an extension of the control (and maybe I should have), but it works, and I have used it in three different applications (as an output window and as a chat log). So, I am happy with it.
In the end, it really is just a matter of how self-contained, reusable, and easy to drop in you want a control to be. If there is already a control that does what you want, and you just want it to look different, then you should definitely use styles and templates to achieve that. However, if you want to make something that doesn't already exist, limiting yourself to using only styles and templates will make the implementation work harder and make the end result less reusable and more difficult to set up additional instances (unless all instances are identical).
The examples of making things like buttons that look different are not examples of what you should use a custom control for. They are just examples of how someone would go about making a custom control for the purpose of teaching the details of the process. If you actually want a customized button, just customize a button.

For implementing virtualization in a non-ItemsControl, is it better to retrofit ItemContainerGenerator, or implement simple custom generation?

We're rolling our own special Items-based control/panel combo that isn't based on a subclass of ItemsControl (there are multiple reasons why we can't do this which I won't get into here) but our control does handle thousands and thousands of data items, so we'd like to implement Visual virtualization.
What we're wondering is if it makes more sense to try and bang the existing ItemContainerGenerator class into our design or roll our own virtualization method.
On the one hand, ItemContainerGenerator already handles virtualization and is very efficient, and tried-and-true code is almost always preferable to starting from scratch, but on the other, the ICG was designed specificially for use with, and relies on features of the ItemsControl, which again, this control is not. Plus, that is a container generator but in our case, we just need to generate and lay out a specific, known visual that represents the data item.
Now, perhaps I'm over-simplifying things, but all I see is a need to determine which items would be visible in the ViewPort, ensure visual representations of those items are created, measured and arranged, then discard any left-over already-created visuals. To keep track of it all, it seems a simple item-to-visual mapping scheme is all that is needed, perhaps with a ItemVisual attached property on the DataItem's ViewModel object. That way when an item is removed/destroyed, we just check if there's an existing visual, and if so, nuke it.
That said, can anyone think of a reason we shouldn't simply roll our own visual virtualization? Again, the ICG does this, but I'm wondering if that's taking a Semi to the store to get eggs.

WPF Canvas - Visual Studio like split view

I'm working on an app, that displayes huge (10000+ elements) graphs in a wpf canvas.
I'd like a feature like in Visual Studio, when you can split the view of an editor (so I can view two distant part of the same graph at the same time).
I have some constraints:
data binding (creating the bindings) of graph elements makes the loading of big graphs very slow, so I'm not using MVVM, the "VM" knows about the view and updates it directly when needed
the children of the canvas are frameworkelements, since I use the Tag property
because of the number of graph elements, I don't want to keep two different view for each element for the two part of the split view
So it should be like displaying multiple parts of the same canvas in different places. You can't set two parents for the FrameworkElements in WPF, so the easiest way is out of question :(
What are my options? Should I reconsider my constraints or there is some workaround for this?
Let me know if you need any more details (it's a big application, so I can't give you every information).
Edit: duplicating with visual brush is not an option since I need proper input event notifications, so both view must be editable.
Options:
Bind the same data to two controls.
Use a visual brush and duplicate input on the real control.
Create a custom graphing control that can output two parts of the graph at once.
If binding to two controls is too slow, then I think you need to rethink your application. The very fact that you have so much data displayed at once that you need a dual view to see separate parts is disturbing. That should raise a red flag. The red flag would notify you that, "What I need, and what I have is different." And you should go back to the drawing board and find out what you really need.
Otherwise, it might be best to create a custom control. The graph is rendering in its entirety even though you only need small portions displayed. If you had your own custom control you could speed up the entire app by rendering only visible portions at a time, and splitting within the control.

WPF: How to use views like ICollectionView and IEditableCollectionView

I understand the syntax but not how really to use it. It's clear in many basic scenarios but as soon as it get's a little bit advanced I start getting a headache.
For example there are many different views but often not clear wich one to use. Also should you use always just one or mix and match. Do you use the view as your itemssource for ItemsControls?
I'm gonna give a scenario. I have items from a database that I need to show info about in a app and also allow to edit and add new. The items form a hierarchy and the models are of different types. So the top level have children and they then have children.
I could show it in a TreeView or some itemscontrol. Problem here is I tend to bind to the children property of the root elements wich returns a List of chilren. Now the children aren't really inside a view, like I can't call editview.addnew() or filter the children straight away. Question is how do I ensure the children are also in a view and their children and so on. Should the model return a view, should I create a seperate view for each children type or even for each parent?
Another thing is if I'm allowing editing should I put the Collections straight into a IEditableCollectionView or wrap it in ICollectionView first (why is that better)?
Is there a good guide to using views that isn't just pure basics?

WPF - CAL - Multiple parents for single instance of control?

I am working on a PRISM / CAL solution, but the problem may be WPF specific:
If I create one instance of an control (e.g. TextBlock) and add it as child to a StackPanel, there is no way to add it as "child" to another StackPanel (parent already set error). I kind of understand the reason (it also occurs when using the RegionManager).
But what is the suggested way if a visual control is very complex and should be created only one time and used in two places? I agree that is does not really make sense to show an identical control 2 times on the screen, but there might be cases where it is useful (e.g. an "Close All" Button).
I know that in the button case, I should just create two buttons both databound to one ICommand. But does this rule also apply with much more complex controls (always create new instances)...
I stumbled on this problem when creating a layout switcher, which creates the button list and the stack panel for each GUI seperately, but uses a static ObservableCollection of buttons as source (which causes strange bugs)..
Any ideas on this topic?
Chris
This is normally handled by templates. That is, you abstract out the data into a particular type, and associate a template with that type. Then you place the instance of that data any number of times into your visual tree and have WPF render it with the template.
In short, don't add a TextBlock to your StackPanel. Instead, add an instance of your data type (eg. Customer) and associate a DataTemplate with the Customer type. There is no way to parent the same UIElement in multiple places.
You can add your control (or collection of controls) as a resource and refer to them via binding in your controls. This will implicitly create a copy (they will be Freezable and WPF will copy them).
Generally you should be using DataTemplates as Kent suggests, but if you have a special case, this will likely work.

Resources