I am working in silverlight.
Made a new UserControl called TextBoxWithButton.
Now i want add a new property to my new control called TextBoxBackground.
I did this :
public partial class TextBoxWithButton : UserControl
{
public Brush TextBoxBackground
{
get{return textBox.Background;}
set{textBox.Background = value;}
}
}
This works fine, but when I try to animate this property I get an exception.
I think it's because TextBoxWithButton should be defined as a dependency property but I don't know exactly how to to this.
You need to turn this into a Dependency Property. For details on implementing a DP, see Custom Dependency Properties.
Once you have this setup as a Dependency Property, just bind your (inner) TextBox.Background to the "local" TextBoxBackground property (in xaml). You can then animate the UserControl's TextBoxBackground property as needed, and the "inner" property will change as well.
Related
I have a simple user control that has One Dependency Property (the control is the model of itself)
The property is not directly bound to anything inside the user control, but I need to Bind its value to the Model of the window (or user control or whatever) where I put my user control.
If I set manually the User control Property Value, the property is modified correctly so I can assume the dependency property in the user control is working.
If I set the value to the Property binding it to my window model like this
<lctrl:InfoIconControl Grid.Row="0" Name="InfoIconTest" IconType="{Binding Path=IconTypeValue}"/>
Where IconTypeValue is a property of the window model, when I set the value of the window model property it does not change inside my user control. I presume I did something wrong but at the moment I have no clue.
Two possibilties come to mind as likely:
Your "model" (you mean viewmodel?) does not implement INotifyPropertyChanged and/or you're not firing the PropertyChanged when IconTypeValue changes its value.
You've done something like this.DataContext = this inside your UserControl and now the Binding is not working because it is looking for the IconTypeValue property inside your control, instead of looking for it in the "model".
Solution to option 1 is easy: implement the interface and make sure you fire the event when the property changes.
Solution to option 2 is simply removing any setting of DataContext inside your UserControl, and instead rely on relative Bindings (RelativeSource, ElementName, etc.) in your control's XAML. Or if you gotta set the DataContext of something, do NOT set the UserControl's one. Instead, set the DataContext of a container INSIDE the UserControl.
In your case, since you're using a viewmodel for your UserControl, using it as DataContext makes sense. But if you wanna support binding to the DependencyProperties of your UserControl, you're then gonna have to set your viewmodel as DataContext of something else... For instance, the first Grid in your XAML.
Just name the Grid:
<Grid x:Name="LayoutRoot">
And set your viewmodel as its DataContext:
InfoIconControlModel mModel;
public InfoIconControl()
{
InitializeComponent();
mModel = new InfoIconControlModel();
LayoutRoot.DataContext = mModel; // this.DataContext = mModel; <-- DON'T DO THIS
}
After that, the Bindings will begin to work. But you've made another typical mistake: you're only calling SetIcon from the CLR setter of your propertty.
public InfoIconType IconType
{
get
{
return (InfoIconType)this.GetValue(IconTypeProperty);
}
set
{
this.SetValue(IconTypeProperty, value);
this.SetIcon(); // <-- This won't work with Binding
}
}
Instead, you must also call it from the DependencyPropertyChanged callback (that you had already defined, on the other hand):
/// <summary>
/// Icon Type dependency Property
/// </summary>
public static readonly DependencyProperty IconTypeProperty = DependencyProperty.Register(
FLD_IconType, typeof(InfoIconType), typeof(InfoIconControl), new PropertyMetadata(InfoIconType.ICPlus, IconTypePropertyChanged));
///<summary>
///
///</summary>
private static void IconTypePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
InfoIconControl ic = sender as InfoIconControl;
ic.SetIcon(); // <-- This will work with Binding
}
I have a control called BasicUserControl2 which contains only a TextBox. I would like to register a dependency property that exposes the TextBox nested inside the control. This so that in a parent control say BasicUserControl1 I can write something like
<tt:BasicUserControl2 TextBox.FontSize="10" />
I currently have the following dependency property:
public TextBox TextBox
{
get { return (TextBox)_textBox; }
set { this.SetValue(TextBoxProperty, value); }
}
public static readonly DependencyProperty TextBoxProperty = DependencyProperty.Register(
"TextBox", typeof(TextBox), typeof(BasicUserControl2));
What kind of property do I need to register? I am trying to avoid having to map properties on the textbox individually to identical properties on the parent UserControl.
You need to create an Attached property instead of Dependency property on your custom UserControl.
I have an image inside a user control that I want to bind it's visibility to a property I have set up in a class object. The dependency properties are set up and working correctly, but I don't know how to set the binding properly on the image.
The user control and class object are in the same namespace. I thought I would need to set the ElementName to the window or the RelativeSource to the class object, but I'm not getting it to work out.
Here's what a dependency property looks like (defined in MigrateUserWizardObject.cs, this inherits from DependencyObject, this resides in the UserAccountMigrator namespace):
public static readonly DependencyProperty DatabaseStepCompletedVisibilityProperty = DependencyProperty.Register("DatabaseStepCompletedVisibility", typeof(Visibility), typeof(MigrateUserWizardObject));
public Visibility DatabaseStepCompletedVisibility
{
get
{
return (Visibility)GetValue(DatabaseStepCompletedVisibilityProperty);
}
set
{
SetValue(DatabaseStepCompletedVisibilityProperty, value);
}
}
Here's an image that I want bound to this dependency property (defined in ProgressUserControl.xaml, this inherits from UserControl, this resides in the UserAccountMigrator namespace as well):
<Image x:Name="DatabaseCompleted" Source="{StaticResource GreenCheckMarkSource}" Visibility="{Binding Path=DatabaseStepCompletedVisibility, UpdateSourceTrigger=PropertyChanged}" Height="20" HorizontalAlignment="Right"></Image>
This is due to the fact that the DataContext of the image is the user control. How can I make this work?
I think you should look into using the Model-View-ViewModel pattern. Instead of setting the DataContext to the UserControl, set it to an instance of another class (ProgressViewModel, for example). This view model would have all the properties you want to bind to (including your DatabaseStepCompletedVisibility property) and makes it much easier. Right now you are wanting to bind some things to the UserControl, some things to another object somewhere else, etc.. and, as you have found, makes it difficult. Here is more information:
http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/432/MVVM-for-Tarded-Folks-Like-Me-or-MVVM-and-What-it-Means-to-Me.aspx
Without going that approach, you have to have an instance MigrateUserWizardObject to bind to. You can put that instance in your UserControl (if you insist on using it as the DataContext), then you can bind the the property of the MigrateUserWizardObject property of the UserControl. Also, your MigrateUserWizardObject doesn't have to be a dependency object or dependency property to bind to. A better pattern would be to make it a plain c# class that implements the INotifyPropertyChanged interface.
I have a custom user control that exposes a DepenencyProperty (ImageData).
I've placed this user control on a page and I bind it's ImageData property to a property of my page's ViewModel (photo).
<localControls:PhotoPicker ImageData="{Binding Path=Photo, Mode=TwoWay}"/>
When the user interact with the control setting the controls ImageData property the Photo property of my viewmodel is updated == Perfect. However if the ViewModel changes the value of Photo, the ImageData property of PhotoPicker is not changed. What could I be missing in getting data from the ViewModel back down to the user control?
UPDATE:
Upon further investigation it seems that the setting from the ViewModel back to the control via the binding, through the dependencyproperty does not fire the setter of the dependency property wrapper property. What a mess. I need to know when that happens, if i can't do that in the setter of the wrapper property where should I do it?
UPDATE 2:
Seems that the only way to find about changes to the DependencyProperty is to add a PropertyChangedCallback in the PropertyMetadata when Registering the property.
Sounds like your view model doesn't send property changed notifications? Extremely simplified, your view model must look something like this:
public class MyViewModel : INotifyPropertyChanged
{
private object photo;
public object Photo
{
get { return this.photo; }
set { this.photo = value; this.OnPropertyChanged("Photo"); }
}
// ...
}
I want a 1-time databind between a checkbox (IsChecked propety) in a childWindow and a nested member variable in it's DataContext object, such that only the initial IsChecked property is set by the member variable. The member variable (binding source) is not INotifyPropertyChanged or marked as a DependencyProperty- but I think that is ok b/c I only want it to be evaluated once- when it gets its initial value.
Binding (in testChildWindow.xaml):
<CheckBox Content="Show Username?" Name="cbShowUser" IsChecked="{Binding Path=User.showUser}"/>
Setting DataContext (in parent window code-behind):
testChildWindow dlgBox = new testChildWindow();
dlgBox.DataContext = (this.DataContext as IAssignDlgViewModel).AssignVM("defaultChildWindow");
dlgBox.Show();
Data Context/Member variable:
public class testChildWindowViewModel : IDlgViewUpdate
{
public User
...
}
public class User
{
public bool showUser;
public User()
{
showUser = true;
}
...
}
If I make the Vm's binding source property (showUser) a dependency property at the (non-nested) testChildWindowViewModel, then the binding works. But all other combinations seem to fail.
Why must it be a dependency (or INotifyPropertyChanged?) property for a 1-time binding?
Why can't I get it to work at a nested level?
Thanks!!!
Ah, looking at the Output window during the binding answered the question for me. The problem was that User was not a property. Changed it to an auto property and the binding works just right now.