Pick functionality from one usercontrol to another - wpf

I have dialog which consist of two user controls bind to their models.
I want to enable user to pick a data point on the chart control from the UserControl1.
I can get the data point on mouse down event of chart control and wan to fill the associated textbox with that value. I am unable to identify the best approach to pass that value back to the UserControl1. Also how will I identify which button has made the call to pick the data point. Note I have to do the same in an MVVM friendly manner.

Its not really about UserControl, more about ViewModels. I suggest your chart Model (which I guess should be a "ViewModel") could raise an event passing the data point as parameter.
To identify which button has made the call, you can memorise it in your UserControl Model (again, ViewModel).

Related

Changing the data in a specific area of a window, Caliburn.Micro, WPF

Here is my need. I think a user control is what I need but I am not sure if its the best or even how to use it.
What I have. My main window has a menu with a "help" menu. When you click help, a new window opens, I have a column, At the top of the left column has a drop down box of "Major Titles", a ListBox below that that populates based on the combo box selection. This will be about 25% of the window width. All this works.
When I select an item in the list box a page,contentControl or user control is displayed to the right with verticle scroll bars so the window does not need to resize, the information I display that changes based on the list box selection will have only visuals like text block, label, images. There will be no user interaction with the changeable pages Just formatted Data.
What would be the best way to approach this? Can anyone offer an easy example?
I was thinking of using a user control and change the user control based on the selected list box item.
Ok, I got this figured. After reading a lot of posts and blogs. Seems people sometimes want to make things more complicated then they actually are.
What I wanted, a permanent list box on the left 1/6 of the window. The list box contained string names for "help subjects". On the right 5/6 of the screen I added a groupbox with header and in group box I added a usercontrol. The content of the control is bound to a property called 'ActiveView'. The list box selected value property is bound to 'SelectedListItem' property.
When you change it set 'SelectedListItem' a method is called 'SetActiveControl'. SetActiveControl has a switch/case that sets like in the example:
``Case "Setup":
ActiveView = new SomeSelectionViewModel();
Break;
I have created a user control in a folder inside the Views folder called HelpControls, I also created the same folder in ViewModels. I have classes matching the user controls and everything is bound together.
Ultimately when you click the list box item, the associated ViewModel is called and in turn populates the user control on the window with the appropriate data.
I need to later look into, using one ViewModel for all the controls, I know that can be done using Cal:Model.View = ViewModel name. In the xaml of the control. I'm just not sure how to call the appropriate user control view when an item is selected. Either way this would become a view first design and I thought I read, Caliburn. Micro was intended as a ViewModel first design.

WPF loading grid child based on treeview click

I'm developing a WPF C# app where I have a tree view control and if the user clicks on a node in the tree, a node-specific detail 'form' appears in a named Grid somewhere else in the form. If you click on a different node in the tree, the displayed detail form checks if the contents are saved, is dismissed, and a new detail form appears in it's place.
What I need is some starting advice. Can I still implement the forms as standalone xaml, then put some some of 'container' in the grid that I throw the form into as a child? Or just add the form as a grid child somehow. How do I programmatically load the form I want in the grid and communicate with it?
Thanks for any assistance!
Corey.
Use an event aggregator design pattern, see here for details:
http://martinfowler.com/eaaDev/EventAggregator.html
You can then have some other code which listens for the node change clicks via the event aggregator and response accordingly. This will decouple your code and make it more testable.
Am assuming you are using mvvm?
If not read up on it - will make it easier.
then you have your form with the treeview on it, bound to its itemsource on the view model.
Usually an items control like a treeview will have a selecteditem property on it.
Bind that to a property on your viewmodel which is of the type of objects contained in your treeview. Call this for example CurrentlySelectedItem.
Your details 'form' can be a control or whatever you want on the same form.
Now depending on how complete your object is - you have at least two options. If your object in the treeview has all the data you need already, then just bind the details to CurrentlySelectedItem.
Obviously it must implement INotifyPropertyChanged to tell the binding system to update the values.
If the object doesn't have enough info, then on the setter of CurrentlySelectedItem you can then fire a method to load the full object and then bind the details to that full object.
Alternativley, another popular approach, you could have the details form as a self contained control that subscribes to a message and when it recieves the message with the key of the treeview object, it loads the required info.

Creating a WPF Textbox Control like Outlook email recipient textbox

I'm looking to create a WPF textbox control that acts similar to the email recipient textboxes in Outlook (the To, Cc and Bcc inputs). I don't necessarily care that much about auto-completion (i've found millions of examples for that), but what I'm really struggling with is how to have delimited text entries in the textbox behave as entities the way they do in Outlook (once a recipient you've entered resolves, that text becomes an 'entity' which you can click to select, right click to get a context menu, etc. it's not longer 'plain text' in which you can place your cursor)...
Does anyone have any high level ideas how to accomplish this? Know of any existing examples (I've googled for hours)?
Thanks so much in advance,
Michael.
My rough thought process would be this... (note: I'm not actually coding it, so my details may be a little off...).
High level behaviour:
the type of data in your control is a list of items which aren't selectable. Therefore your control is, approximately, an ItemsControl (in terms of visual/XAML, it's an ItemsControl with a WrapPanel style layout and very simple TextBlock for the item template).
when your control gains focus, you need to switch the template to be a TextBox
when your control loses focus, you need to split the inputted text and convert it to a list for display.
Therefore, thinking code:
you need a UserControl, possibly derived from ItemsControl. That gives you basic behaviour to represent a list of items.
you need a custom DependencyProperty on your control that represents the delimited string.
when the string property changes, you need to parse it and replace the list of items in the control.
when the list property changes, you need to replace the string property with a suitably-delimited list.
In terms of code-behind, that part should be pretty simple. Then, for the XAML template...
you need a base template that displays your Items property as a list, using the WrapPanel layout mentioned above.
you need a trigger that replaces this template when the control has focus.
the replacement template should be a TextBox that is bound to the string property of the control.
the default binding behaviour on a TextBox will only push a new value when the TextBox loses focus, so you need to think about whether you want to make, say, an "Enter" keypress move focus (thus reverting the template to the list version - when the string property's value changes, your codebehind will update the list).
This should give you the basic behaviour. You should be able to bind either the list property or the string property from outside of the control, though you may have to be careful about what happens if you bind both properties since there's a two-way dependency between them...

Weird two controls / same datasource problem

This is using winforms.
I have a listbox and a combo box, both tied to the same datasource, same display members, same value members. All is bound just fine and the items show up in both the controls.
The problem is when I change a selection in one control, it moves to the same index in the other control. I don't have any events tied to either control. It is just happening on its own. Has anyone ever run into this?
This is because both the controls share the same BindingContext/CurrencyManager. Controls inherit the BindingContext from their container control. A BindingContext maintains only one CurrencyManager per DataSource. If you want to have two different CurrencyManagers, you need to have two BindingContexts.
So when once of the controls selection is changed, currencyManagaer.Current gets updated. This affects all the controls that share the same DataSource.
Instantiate a new BindingContext and assign it to the BindingContext property of one of the ComboBoxes:
comboBox2.BindingContext = new BindingContext();
This should solve the problem.
The datasource is a separate object. When one of the controls changes the datasource active row it sends out an update notification to the other controls to move accordingly. This is normal and expected behavior.
The idea behind it is to simplify navigating record sets while keeping all the bound controls in sync.
If you don't want that, use two datasources tied to the same underlying data.
I think that might be intended to be a feature. For Master/Detail type forms.

How can I get WPF binding to occur on controls which have not yet been shown?

I have a custom text box control which raises a routed event when its TEXT property changes. This text property is data bound to a property on our view-model object.
When I place this control on a TabControl page or Expander control, it appears as if data binding only occurs when the control becomes visible for the first time, therefore I never receive any of the routed events until I swap to the tab the control is on or expand the expander.
Is there any way I can force data binding to occur before the control is shown?
Sounds like you relying on the data binding to genreate the routed event is the wrong approach. Instead you need to have your Model or ViewModel generate an event when the text is modified and then you watch this event from an appropriate place in your View.
Not very likely. WPF is a fairly efficient framework and won't do any work that it doesn't absolutely have to. This includes scenarios like data binding. Why bother exercising a collection for a control that might not ever be shown?

Resources