I'm new to both Caliburn and WPF, so excuse me if it is a rather trivial question.
The scenario is the following: I have multiple controls (like buttons and textboxes - the latter is the important part). Their state (Enabled/Disabled) are dependent on a boolean property.
The first suggested method I tried was using the Can[FunctionName] convention and NotifyOfPropertyChange(() => Can[FunctionName]). It worked well with the button, but it did not work with the textbox.
How do I bind IsEnabled property to a state without using the code-behind of the View?
The code I tried in the ViewModel didn't work for the textbox:
private bool _buttonEnableState = true;
public bool ButtonEnableState
{
get
{
return _buttonEnableState;
}
set
{
_buttonEnableState = value;
NotifyOfPropertyChange(() => CanTheButton);
NotifyOfPropertyChange(() => CanTheTextBox);
}
}
public bool CanTheButton
{
get
{
return ButtonEnableState;
}
}
public void TheButton()
{
}
public bool CanTheTextBox
{
get
{
return ButtonEnableState;
}
}
From the View:
<Button x:Name="TheButton" Content="This is the button" ... />
<TextBox x:Name="TheTextBox" ... />
Thanks in advance!
Have you tried the obvious?:
UPDATE >>>
So, continuing the conversation from the comments... now you have a
public
property in yourAppViewModel
class and an instance of that class is set as theDataContext
of your view that contains theButton
andTextBox
controls?Let's see if the
Binding
is really working or not... try changing your code to this:If the
Button.Content
is set then theBinding
works just fine and you have a different problem.UPDATE 2 >>>
As @Charleh mentioned, you also need to make sure that you have notified the
INotifyPropertyChanged
interface of the change of property value:I don't think what I'm about to suggest is necessarily the correct way of doing things, but it may give you the result you're after.
In order to get the control to be disabled based on a
Can<name>
property, you need to confirm to the conventions that Caliburn uses, so in this case, supplying a function<name>
should work:As a result of the default conventions, I believe this will be called every time the
KeyDown
event is fired.That said, you probably want to bind your text content to something, and you'll want to use the
x:Name
property convention to choose which property, that means you'll have to attach theTheTextBox()
function in a different way, you should be able to do that using theMessage.Attach
property in theCaliburn
namespace.So your TextBox could look like this (where you've added the following namespace
xmlns:cal="http://www.caliburnproject.org"
):Backing that up in your ViewModel, you'd have:
You should then see the Enabled/Disabled behaviour, and be use the
SomeTextProperty
.I'm not entirely sure I like this way of doing things, I just had a quick play to see if it worked. The following answer might be a cleaner solution, and establishes a new re-usable convention:
Adding a convention for IsEnabled to Caliburn.Micro
As a slight aside (not a direct answer), depending on how complicated your control/form is, you could investigate using multiple
Views
for the sameViewModel
, in the past I've set up aReadOnly
andEditable
view, and used a single property on theViewModel
to toggle between the two (essentially setting the entire state of theViewModel
). There are already default conventions so you can use multiple views with relative ease.