ListView with external buttons - Custom or User Control? - wpf

I need a listview with multiple buttons for scrolling. E.g.
ScrollToTop Button
ScrollUp Button
ListView
ScrollDown Button
ScrollToBottom Button
I have got the buttons working in a WPF application by using the code mentioned here. Now, I need to reuse this by making it a control(lookless?). The layout of the listview and buttons can be horizontal or vertical. Should I use custom control or user control?

Here's what I'd recommend.
Don't use any pre-composed elements. Create a behavior ScrollList, accepting two parameters - Direction and Target, Direction will be Top || Bottom, Target you list - again you can use ElementName binding.
The reason why I'd recommend this approach is the actual code required to scroll your list is tiny, while managing layouts via properties in WPF is proved to be mess an anti pattern (yes you can go ControlTemplates, but it's definitely too havy for what you're trying to do).
If behaviors are too complex just consider creating a couple of commands.

Related

Problems writing too much custom controls in WPF

I am working on new WPF/MVVM project, where I see all most all controls are written for different needs, right from textbox to treeview. All are rewritten for simple need, for example, grid,stackpanel control are rewritten to add space between each item and textbox is rewritten to include label for it so that it has both label and text input are on itself.
My question : Is there any serious issue we would encounter because of this customization?
Already, I am seeing issues with aligning all controls, will i would see any more issues because of this?.
You should never create a custom or user control to add margins, a label to a TextBox, or a new ItemTemplate to a ListBox.
UserControls are for grouping frequently used combinations of controls into one reuseable control. An example may be a custom List-of-Values control that opens a dialog. This would be fine to implement as a UserControl.
Custom controls are good when a native control does not suit your needs. Say that you want to reimplement a DateTimePicker from scratch because the native one doesn't include milliseconds.
There are no serious issues as such, but you may find yourself maintaining all these controls for the next many years without there being a need to do so.
Settings Margins should be done in the View where you are using it, or on a Style in a ResourceDictionary.
This is of course only my opinion (and that of many others, I except), but if you find that the majority of your controls are 'customized' this way, you are doing it wrong.
Style and Templates rather than UserControls and custom controls.
The main issue is that you lose the ability to alter margins only in a single view. If you change your custom controls' inner paddings and margins, you will be changing all the views in your solution. If you use a style, you can always override it by defining a new style in the view, or by setting the property directly.

Is it possible for WinForm controls (Panel,etc.) to grow like a webform control?

I'm converting an app from ASP.NET WebForms to WinForms. There is one asp.net page which contains a ListView/Repeater that contains several custom controls, which in turn contain a ListView with other custom controls. Basically the layout looks like a TreeView, but on each node/leaf there are few controls like comboboxes, etc.
When this is in ASP.NET, the page automatically lays itself out, so it is several screens tall - if I add 20 buttons into a Panel, it will grow and the browser will get scrollbars.
I'd like to do the same thing in a WinForms application - so I'll have a user control that will contain a lot of controls in a some variation of Panel (Flow, Table layout), and the controls might have another controls inside them, etc.
The problem is, that when I make winforms app, each control has specific height in the design time. I'd like some user controls to be able to grow with their contents - so they'll add up. In the main Form, there should be a vertical scrollbar, just like in the web browser when the generated page is taller than the screen.
I'd just like to get some general pointers in the right direction. Thanks.
Use Anchor and Dock container properties.
Yes, to expound on Anchor and Dock...try this
-Place a Panel on an empty form, and set its dock property to Top
-place a textbox in the panel, and Dock it to Full...it should fill the whole top panel
-Place a splitter on the form, and if not already docked correctly, set its dock to top
-place another panel below the splitter, and set its Dock to Fill
-place another textbox inside the lower panel and fill it as as well
Now you have a form with two resiable textboxes and will resize when the form does.
*you may have to set the textbox MultiLine property to true but not sure.
Hope this helps.
Anchor the controls to the parent. Anchoring all four sides will cause it to stretch.
If the Anchoring and Docking answers don't work for you, there is another option. It's not pretty, but you can access a control's properties and change them dynamically during runtime. You'd do something like: if(listBox.Items.Count > [yourVal]) listBox.height = [yourFormula] or something.
It's been a while since I've done a Win Form (and I don't have my IDE fired up at the moment) but I'm pretty sure there's even a ScrollPanel or other scrolling control that you can set on your form.
That said, when you're working with WinForms, the less scrolling you can make your users do, the better.

Re-using Buttons in WPF

I have a bunch of different objects that are commonly edited in the same TabControl using different DataTemplates, but I want each DataTemplate to have a common look and feel with Ok and Cancel buttons at the bottom right of each tab that will close the tab or save the content and then close the currently selected tab. What's the best way to place buttons on each tab ? Is there a way to do it without copying and pasting the buttons and stack panel across all of my data templates ?
Sure, you can create your own OkCancelSaveControl. In WPF, creating a "user control" is much easier than it sounds. Here is a tutorial. In a nutshell, you
create a new user control,
create properties in the user control that give the your control the information it needs to perform its duties (e.g. the tab that it's supposed to close or the data object that it's supposed to save),
if necessary, create events that the user control raises (OkClick), in case some tab requires special treatment.
I would make a custom control, lets call it MyCoolTabItem, that inherits from the TabItem class, and just throw your buttons into the control. Then just add a MyCoolTabItem instead of a TabItem to all of your TabControls and it will have all of your buttons on it.
You could make a base view class that held those buttons. Views that needed the buttons would inherit them and common functionality.

how can i change controls when a button is pressed in xaml

i am trying to create a wpf app and have different parts in user controls.
in the navigation i have some buttons (now using the ribbon ctp). is it possible to change the main user control when different buttons are pressed in xaml. or is this just a bad way to do things?
sorry, really new to xaml and im trying to get my head arround it.
Further to what Carlo has said,
The way we do it is to have a blank grid in the place you want your controls to all appear and then use BlankGrid.Children.Clear() and BlankGrid.Children.Add() to set up which control is visible in this position.
We found that was the nicest programatically as we have a large number of custom controls, but Carlo's method would work nicely if you wanted to use the designer.
I think this is a pretty regular procedure in WPF. In my experience, me and other programmers put the controls where we want to show them and make their visibility hidden, collapsed or visible depending on what we want to show the user.

Encapsulating and customizing a third party WPF control

I'm interested in customizing a 3rd party control, such as Telerik's RadGridView, as a standalone control, for example adding New Row and Delete Row buttons above the grid, yet still supporting XAML manipulation of the internals of the control by the window upon which my control exists (i.e. for the window to add its own style to a column of the grid).
Is there a way to add the buttons, etc. with templates? Styles?
My current "solution" is to inherit from the RadGridView, but I'm stuck on how to add the features I need.
Thanks!
My suggestion is to use composition over inheritance.
You can create your own control (UserControl should do the work). Then you can define the layout (may be in Grid panel): buttons on the top, RadGridView bellow them, etc. For custom column styling you can use DynamicResource trick. Set the styles of the columns you want to modified with DynamicResource. This way when the control is added to the logical(visual) tree; WPF will walk up the control tree and find appropriate resource. This way in each window/page resources you can define the different resource.
Another idea that come to my mind is that you can extract the buttons as a separate control. The only reference that they will need will be RadGridView and you can use binding with element name to provide it.
I would go the custom UserControl route instead of inheritance route. Styling and theming work strangely when you're dealing w/sub-classes. Unless you're planning on duplicating and modifying Telerik's ControlTemplates and DataTemplates, it can get pretty hairy.

Resources