How to expose combobox Databindings on a usercontrol - c#

I have a combobox on a usercontrol. I can expose the datasource however I cant expose the actual bindings.
If you add a normal combobox to a form and go to the databindings property you can choose selected value, text etc.
After this is chosen the designer automatically creates a
combobox.databindings.add("SelectedValue", datasource, columname, true));
How can I expose a combobox on a user control so that it has the above behavior

It's probably not considered best practice to expose your controls like this since after all, part of the point of using a UserControl is to hide the details of the child controls.
Try exposing the control on the UserControl as a property:
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ComboBox ComboBox {
get {
return this.comboBox1;
}
}
}
If you are only interested in the control's DataBindings, then try to just expose that information:
public partial class UserControl1 : UserControl {
public UserControl1() {
InitializeComponent();
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ControlBindingsCollection ComboDataBindings {
get {
return this.comboBox1.DataBindings;
}
}
}

Related

Interact with SelectemItem of Treeview

I have implemented the SelectedItem of a treeview according to the following article: Data binding to SelectedItem in a WPF Treeview
The SelectedItem works perfect and it truly reflects the item selected.
Now I want to interact with the selected item, but I'm not sure how. I can create an instance of the BindableSelectedItemBehavior class, but this is not the instance containing the data I'm looking for. How to access the class instance holding the SelectedItem of the treeview?
This is a highlight of my code:
namespace QuickSlide_2._0
{
public class BindableSelectedItemBehavior : Behavior<TreeView>
{
...
}
public partial class Window1 : Window
{
.....
private void New_subject_Click(object sender, RoutedEventArgs e)
{
// here the code to read the instance of the class BindableSelectedItemBehavior and interact
// with the selectedItem when I click on the button
}
}
}
Maybe I'm looking totally in the wrong direction. Your help would be highly appreciated!
You want to use MVVM so that you can bind the dependency property of your behavior and then you can access the value of the SelectedItem that you made.
public class BindableSelectedItemBehavior : Behavior<TreeView>
{
//Dependency property called SelectedTreeViewItem register it
}
public partial class Window1 : Window
{
public Window1()
{
DataContext = new WindowViewModel();
}
private void New_subject_Click(object sender, RoutedEventArgs e)
{
// here the code to read the instance of the class BindableSelectedItemBehavior and interact
// with the selectedItem when I click on the button
var windowViewModel = DataContext as WindowViewModel;
var selectedItem = windowViewModel.SelectedItem;
}
}
public class WindowViewModel()
{
public object SelectedItem { get; set; } // You want to change object to the type you are expecting
}
and on your View
<TreeView>
<TreeView.Behaviors>
<BindableSelectedItemBehavior SelectedTreeViewItem="{Binding SelectedTreeViewItem,Mode=TwoWay}">
</...>
</...>

C# UserControl - A circular control reference has been made

I want to access fdtlc.Controls instead of fdtlc.flpFlightList.Controls
public partial class FlightDetailListControl : UserControl
{
public ControlCollection Controls //Error circular control reference has been made
{
get
{
return flpFlightList.Controls; // flpFlightList is a FlowLayoutPanel
}
}
public FlightDetailListControl()
{
InitializeComponent();
}
}
FlightDetailListControl and FlowLayoutPanel are both Controls, so they both already have a ControllCollection named Controls inherited from UserControl. You'll have to pick another name for your property in FlightDetailListControl.

Making a Generic UserControl which can be accessed by other view

I have UserControl A given below with two Radio Buttons.
This UserControl view has its ViewModel.
Question:
I again have two Views Create and Edit.
I want to use the above mentioned UserControl within Create/Edit with requirement that i can make the radiobuttons or any of the elements in UserControl to be Visible or Hidden based on the requirement in Create/Edit View.
Eg: Create May not require Radio button 1 and 2.So only Rectangle must be displayed.
Whatever input i give in the list or textbox must be updated in UserControl's ViewModel and the search result after clicking on button must be sent to Create/Edit accordingly.
Note:Create/Edit have their own ViewModels.Please suggest which approach is best considering MVVM
The Control has to be placed in the grayed out area as shown in rectangle for Create/Edit View
You can create DependancyProperty inside your UserControl like
public static readonly DependencyProperty RadioButtonVisibilityProperty=
DependencyProperty.Register( "RadioButtonVisibility", typeof(Visibility),
typeof(MyUserControl));
public Visibility RadioButtonVisibility
{
get { return (Visibility)GetValue(RadioButtonVisibilityProperty); }
set { SetValue(RadioButtonVisibilityProperty, value); }
}
and inside your UserControl's xaml Set the radiobutton's visibility like
<RadioButton Visibility="{Binding Parent.RadioButtonVisibility,ElementName=LayoutRoot}"/>
and in your main View(Create/Edit) do like this
<MyUserControl x:Name="Edit" RadioButtonVisibility="Visible"/>
or
<MyUserControl x:Name="Create" RadioButtonVisibility="Hidden"/>
And dont forget to give your UserControl's parent Grid the name "LayoutRoot"
like
<Grid x:Name="LayoutRoot"/>
It might be a good idea to have the UserControl be driven by some abstract BaseViewModel. Then you create two sub-classes EditViewModel and CreateViewModel which you then use based on the context.
Quick crude example for the radio buttons:
public abstract class BaseViewModel
{
public bool ShowRadioButtons { get; protected set; }
}
public class EditViewModel : BaseViewModel
{
public EditViewModel()
{
ShowRadioButtons = true;
}
}
public class CreateViewModel : BaseViewModel
{
public CreateViewModel()
{
ShowRadioButtons = false;
}
}

Create ToolTip for Custom UserControl

I need to understand how to utilize a ToolTip with a custom UserControl. Just creating the ToolTip on a form and assigning the specific control a ToolTip (via SetToolTip) obviously will not work.
What properties do I need to give the custom UserControl in order to assign ToolTip text to it? Do I need to add a ToolTip on the usercontrol form? How can I go about doing this?
Please provide a code sample or something for me to visualize.
Thank you!
Put a ToolTip on your UserControl (use the designer, just like you would put one on a form), and add a public property to your UserControl like:
public string TextBoxHint
{
get
{
return toolTip1.GetToolTip(textBox1);
}
set
{
toolTip1.SetToolTip(textBox1, value);
}
}
Create SetToolTip method in user control and set tooltip for each user control's subcontrol:
public partial class SomeUserControl : UserControl
{
public void SetToolTip(ToolTip toolTip)
{
string text = toolTip.GetToolTip(this);
toolTip.SetToolTip(subControl1, text);
toolTip.SetToolTip(subControl2, text);
// ...
}
}
Set tooltip text for user control instance in parent control designer. This adds in .designer file:
this.toolTip1.SetToolTip(this.someUserControl1, "Some text.");
Call SetToolTip method of user control instance with ToolTip parent control instance from parent control's constructor:
public partial class ParentForm : Form
{
public ParentForm()
{
InitializeComponent();
someUserControl1.SetToolTip(toolTip1);
}
}
This is the correct way to implement a serialized ToolTip property:
public partial class YourControlClass : UserControl
{
// Serialized property.
private ToolTip toolTip = new System.Windows.Forms.ToolTip();
// Public and designer access to the property.
public string ToolTip
{
get
{
return toolTip.GetToolTip(this);
}
set
{
toolTip.SetToolTip(this, value);
}
}

C# how to implement databinding without Control?

Is there a simple way to implement databinding when neither of both classes is of type Control?
In my case, I would like to bind a variable to a property of a custom ToolStripButton.
EDIT for clarification: when binding to a Control, I can use Control's DataBindings collection. However, I am searching for a way to bind properties regardless of the source and target Type.
EDIT: using winforms
You can probably do this by using Truss.
Truss provides WPF-style databinding for any class that implements INotifyPropertyChanged. It gives you a bit more flexibility in this, since it doesn't restrict the classes to being derived from a specific base class.
I use this Implemetation of IBindableComponent on the ToolStripButton, found here. The BindableToolStripButton allows you to use Databinding like with a normal Control.
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class BindableToolStripButton : ToolStripButton, IBindableComponent
{
public BindableToolStripButton()
: base() { }
public BindableToolStripButton(String text)
: base(text) { }
public BindableToolStripButton(System.Drawing.Image image)
: base(image) { }
public BindableToolStripButton(String text, System.Drawing.Image image)
: base(text, image) { }
public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick)
: base(text, image, onClick) { }
public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick, String name)
: base(text, image, onClick, name) { }
#region IBindableComponent Members
private BindingContext bindingContext;
private ControlBindingsCollection dataBindings;
[Browsable(false)]
public BindingContext BindingContext
{
get
{
if (bindingContext == null)
{
bindingContext = new BindingContext();
}
return bindingContext;
}
set
{
bindingContext = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ControlBindingsCollection DataBindings
{
get
{
if (dataBindings == null)
{
dataBindings = new ControlBindingsCollection(this);
}
return dataBindings;
}
}
#endregion
}
Assuming you have a class MyClass implementing INotifyPropertyChanged, use it just like you would when binding to a control property:
bindableToolStripButton1.DataBindings.Add("Enabled", myClass1, "MyBooleanProperty");
Use dependency properties (your property in your ToolStripButton should be) and create a property for your variable in your other class and create a binding and set it to the property of your ToolstripButton.
I guess that's about the easiest way to do it.
EDIT: That's only for WPF...
Else implement INotifyPropertyChanged and when your variable changes, it should automatically change in your ToolStripButton.
For similar behaviour like Controls being bound to object properties, for any Type you can implement the same interfaces.
Based on that thought, you can subclass ToolStripButton (or desired Type to have bindings) and implement IBindableComponent for it. This works for all kinds of source and target Types as long as they're not sealed. For example, your tool strip button:
public class BindableToolStripButton : ToolStripButton, IBindableComponent {
//...
This will cause the BindableToolStripButton to have its own .DataBindings property whereas the base ToolStripButton class doesn't have such a propery.
You would need to follow through on filling out implementation details using examples seen here from Microsoft for ISite, IBindableComponent, IComponent and any inherited interfaces.
Then you would add Binding instances to any instance of BindableToolStripButton.
(Note: I only have fragements so will make my first community wiki post - and we'll see how that goes... )
I written some basic databinding stuff through reflection. It works on any object and doesn't need to implement something special (no INotifyPropertyChanged, it just works) it is part of my editor at http://github.com/filipkunc/opengl-editor-cocoa look at HotChocolate/Bindings (like re-implementation of Cocoa KVC, KVO into .NET) folder. You can see it in action in HotChocolateTest project.
There is another quick and simple solution which consists in creating properties in the Form, and bind them:
public MyForm : Form
{
...
public bool CanDelete
{
get { return deleteToolStripButton.Enabled; }
set { deleteToolStripButton.Enabled = value; }
}
public MyForm()
{
...
this.DataBindings.Add("CanDelete", this.MyModel, "DeleteAllowed",
false, DataSourceUpdateMode.Never);
...
}
}
Assuming that MyModel contains a DeleteAllowed property which notifies its changes.

Categories