I have a Label I am trying to bind to a property. My DataContext is a public Class that implements INotifyPropertyChanged.
My property is defined in my public class like this:
public string ProgressMessage
{
get { return _progressMessage; }
set
{
if (_progressMessage != value)
{
_progressMessage = value;
NotifyPropertyChanged("ProgressMessage");
}
}
}
So why in the world does it show up in intellisense like this (NOT public):
Is this why does my label not update when I change the value of ProgressMessage??
I have done the Mode=TwoWay, UpdateSourceTrigger=PropertyChanged and every other combination I can think of, can anyone help or point me in the right direction?
It seems to me that the symbol you see that kind of looks like a lock is not actually a lock. Instead it seems to be identifying properties on the data context that you can to bind to. I was able to recreate this issue and successfully binded to a property that had the symbol.
If you go ahead and type {Binding Path= You will see that it only shows you possible binding paths:
Related
I need to make few buttons like this:
<fluent:Button
Size="Middle"
Visibility="{Binding Path=SomeTestingMethod}"
Command="{Binding Path=OtherMethod}" CommandParameter="PP"
Some Text</fluent:Button>
visible or not in case of "CommandParameter". I tried:
public Visibility SomeTestingMethod(object o)
{
return o.ToString == "something" ? Visibility.Visible : Visibility.Collapsed;
}
But compiler do not even check it. Also tried stuff like this:
private Visibility _someTestingMethod;
public Visibility SomeTestingMethod
{
get {
var commandExecutor = new RelayCommand(ButtonVisibility);
return _statusButtonsVisibility;
}
}
public void ButtonVisibility(object o)
{
_statusButtonsVisibility =
o.ToString == "something" ? Visibility.Visible : Visibility.Collapsed;
}
"SomeTestingMethod" is then reached but "ButtonVisibility" not.
I Have found other ways to reach visibility, but none of them alows me to get CommandParameter.How to do it correctly?
I have a few comments about the code presented.
First off, do you really want to make the button disappear if the user may not click it? I ask because the ICommand interface has a CanExecute() method which can hold logic to determine if the command may be executed. When a button is bound to a property that is an instance of an object implementing the ICommand interface, the button will automatically enable/disable itself based on the results of the CanExecute() logic. Note, that if that logic does something on a different thread, you may have to force a re-query of the command availability.
If you truly want the button to disappear rather than being disabled, as mentioned by #Jason Boyd in the comments, this is best accomplished by binding the visibility to a Boolean property in the view model and using a BooleanToVisibilityConverter to show/hide the button based on true/false of the property.
The view model should implement the INotifyPropertyChanged interface to communicate property changes to update the binding target.
Hopefully, that gives you a start in the right direction.
You can't get CommandParameter in property which you bind to Visibility property.
Get parameter in OtherMethod method and change SomeTestingMethod property.
Or you can use custom BoolToVisibility converter for using parametr.
I'm struggling with an issue where the following binding seems to have no impact on the UI:
<Toolbar MaxWidth="{Binding AllowedHorizontalSpace}" />
Property and field:
private int allowedHorizontalSpace;
public int AllowedHorizontalSpace {
get { return this.allowedHorizontalSpace; }
set {
this.allowedHorizontalSpace = value;
this.OnPropertyChanged(nameof(this.AllowedHorizontalSpace));
}
}
In the function that listens for monitor size changes:
this.AllowedHorizontalSpace = (int) (monitorWidth * 0.4)
What am I missing? The size of the control just does not want to change! The same error persists for MaxHeight as well.
I have tried manually changing this value using the tool snoop. The change is reflected in the control when I do this.
In comments, it comes out that when the monitor size changes, the setter for AllowedHorizontalSpace is called but not the getter.
The INotifyPropertyChanged implementation looks right from here, and the whole thing works correctly when AllowedHorizontalSpace is set via Snoop, so it is right, and the DataContext must be an instance of your viewmodel.
This kind of thing is commonly caused by there being a redundant viewmodel instance. Often, one is created in the XAML, and another is created in the codebehind constructor. The second instance assigned to DataContext is the one the property will be bound to, but you may be setting the property on the first. In that case the setter would execute on the first, but since no bindings are using that instance as a source, nothing would call the getter.
And you mention that the viewmodel's Initialize() method is unexpectedly being called twice, which is what I'd expect if the above were the case.
The problem is that AllowedHorizontalSpace is not a dependency property yet you are using the dependency property change notification.
The thing to do is to implement INotifyPropertyChanged on the view model. Change the property implementation to the following and everything will start working.
public int AllowedHorizontalSpace
{
get { return this.allowedHorizontalSpace; }
set
{
this.allowedHorizontalSpace = value;
// this.OnPropertyChanged(nameof(this.AllowedHorizontalSpace));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AllowedHorizontalSpace"));
}
}
I have an class, Loans and I have an instance of it in my ViewModel.
I bind to multiple properties in Loans, like
loan.amount;
loan.name;
Etc. I only raise INotifyPropertyChanged on loan itself, and the rest of the properties don't raise it. IE
ViewModel{
loan { get; set { notifypropertychanged("loan")}
Everything I read says this shouldn't work, but it does...in fact, all of loans properties are binding properly and updating property. I always thought you have to raise notifyproperty changed on each and every property, and can't just do it at the main object. Am I missing something?
This is working the way it should be. When you raise the property change, binding framework goes and get the updated value for the property.
Here when you are raising the property change on property of custom type (loan) in your VM, binding framework will get the updated value of loan and will hit getter of each and every property of 'loan' bound on the UI.
No, that will work fine. You're specifying the full path to the property so anything that changes along that path will cause the binding to refresh. It also works if you do something like this:
<StackPanel DataContext="{Binding loan}">
<TextBlock Text="{Binding amount}" />
</StackPanel>
In this case you're not specifying the full path in the TextBlock binding but its parent is bound to a property that does change notification and again it will inform its children if it sees there's been a change. Where you don't get change notification is if you do something like the above and keep loan the same but change amount.
Bear in mind there are different times when change notification is applied. If your UpdateSourceTrigger is set to "PropertyChanged" and you want updates to be applied the instant a value changes then yes, you have to apply it to each and every child member. If it's LostFocus then they'll all get done in one go once the focus is lost irrespective of whether or not they support change notification.
The change notification only works when setting the loan object, not on its properties.
loan.amount = 123;
This uses the [loan] Getter and then then [amount] Setter.
If you need to listen form the parent object then you could set the loan as a private variable and expose the loan properties from the ViewModel
ViewModel
{
private Loan _loan
public decimal loanAmmont
{
get { return _loan.amount; }
set
{
_loan.amount = value;
notifypropertychanged("loan")
}
}
}
Or add the change notification to the loan properties and register to their change from the parent object
ViewModel
{
private Loan _loan;
public Loan loan;
{
get { return _loan; }
set
{
_loan = value;
_loan.PropertyChanged += NotifiyLoanChanged;
}
}
void NotifyLoanChanged(object sender, EventArgs e)
{
// invoke my events to ViewModel listners
notifypropertychanged(e.PropertyName);
}
}
http://msdn.microsoft.com/en-us/library/ms743695(v=vs.110).aspx
Hi I have a viewmodel where i can track the value of a certain item in the constructor. I am opening a dialog window using the MVVM model.
example
private int _myField;
public ClassName(int MyProperty)
{
_myField = MyProperty;
}
public int MyIntProperty
{
get{ return _myField;}
set { _myField = value;}
}
this is all perfect obviously.
but as soon as the window opens the value in the viewmodel changes.
lets say the _myField goes from 1 to 8 with out any interaction. i've walked through the code and there are no other interactions with the field.
also not in the code sample is the bound property.
anyone every came accross this before. it has me stumped.
Edit: included missing property from example
You should either:
1) Implement INotifyPropertyChanged on ClassName. This will allow you to raise the PropertyChanged event when you change MyIntProperty. WPF will listen to this event and update the UI accordingly.
or
2) Make ClassName inherit from DependancyObject and MyIntProperty a dependency property. This will take care of everything for you.
i`m trying to design a dialog window which will display different messages depending on what case will be true.
so for example when i have a
<CustomDialog Content="{Binding Path=Name}"/>
is there a possibility to change the Binding Path=Name to Path=Whatever or how do you implement something like that ? When the Control should use other resources on runtime.
--------------edit
I ok i`ll try to describe my problem better ;)
I have an ResourceDictionary with strings for example
<System:String x:Key="Message1">Message1</System:String>
<System:String x:Key="Message2">Message2</System:String>
<System:String x:Key="Message3">Message3</System:String>
So when I now call my UserControl
Doing it customdialog.visibility = true; for example
<CustomDialog Text=”” />
I want to define which key from the resourcedictionary is taken when the dialog popups up.
something like customdialog.text = Message1; but Loaded from the ResourceDictionary
is that possible or is there an better way of doing something like this ?
You may provide another content to the same property Name at runtime in code-behind. Suppose you have Initialize (or may be Show) method in your CustomDialog and the last one implements INotifyPropertyChanged:
public class CustomDialog : INotifyPropertyChanged
{
//Your implementation of class goes here
public void Initialize(string message)
{
Name = message;
Visibility = Visibility.Visible;
}
public string Name
{
get {return _name;}
set
{
if (_name != value)
{
_name = value;
raiseOnPropertyChanged("Name");
}
}
}
//Your implementation of class goes here
}
In method Initialize there will be updated Name property and your control will be shown. When there will be setting of Name property must be raise PropertyChanged event which will tell presentation that binded value has updated and to reflect it in the UI.
The easiest way I can think of would be to bind to the parent item, not to a child property, and then use a DataTemplateSelector to select a different template at run-time, depending on some condition involving the bound object or its properties.
Alternatively, if the Content has well defined types, you only need to define DataTemplates with specific data types, and they will be automatically used to display objects of those types.
Not knowing more about the context I can't be much more specific, but if you search for more information on DataTemplates and DataTemplateSelectors you should be fine - you can find a lot of useful information here.