This is MVVM application. There is a window and related view model class.
There is TextBox
, Button
and ListBox
on form. Button is
Things look much clearer now with the edits, thanks! This might be a stupid question (I'm somewhat tired of a long day's work), but why don't you bind to the command directly, instead of through a static resource?
<Button Command="{Binding AddObjectCommand}">Add</Button>
Try raising CanExecuteChanged
when your property changes. The command binding is really distinct from the property binding and buttons bound to commands are alerted to a change in status by the CanExecuteChanged
event.
In your case, you could fire a check when you do the PropertyChanged
on the bound property that would evaluate it and set the command's internal CanExecute
flag and then raise CanExecuteChanged
. More of a "push" into the ICommand
object than a "pull".
Since you are using the DelegateCommand, you can call it's RaiseCanExecuteChanged method when your text property changes. I'm not sure what you are trying to accomplish with your CommandReference resource, but typically you just bind the commands directly to the button element's Command property:
<TextBox Text="{Binding ObjectName, UpdateSourceTrigger=ValueChanged}" />
<Button Command="{Binding AddObjectCommand}" Content="Add" />
This would be the relevant portion of your view model:
public string ObjectName
{
get { return objectName; }
set
{
if (value == objectName) return;
value = objectName;
AddObjectCommand.RaiseCanExecuteChanged();
OnPropertyChanged("ObjectName");
}
}
If ElementName binding does not work, use:
<Entry x:Name="Number1" Text="{Binding Number1Text}" Keyboard="Numeric"></Entry>
<Entry x:Name="Number2" Text="{Binding Number2Text}" Keyboard="Numeric"></Entry>
<Button Text="Calculate" x:Name="btnCalculate" Command="{Binding CalculateCommand}" IsEnabled="{Binding Source={x:Reference Number1, Number2}, Path=Text.Length, Mode=OneWay}"></Button>
or use:
<Entry x:Name="Number1" Text="{Binding Number1Text}" Placeholder="Number 1" Keyboard="Numeric"></Entry>
<Entry x:Name="Number2" Text="{Binding Number2Text}" Placeholder="Number 2" Keyboard="Numeric"></Entry>
<Button VerticalOptions="Center" Text="Calculate" x:Name="btnCalculate" Command="{Binding CalculateCommand}">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding Source={x:Reference Number1, Number2},
Path=Text.Length}"
Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Button.Triggers>
Echoing Abe here, but the "right" path to take here is using:
public void RaiseCanExecuteChanged();
exposed on DelegateCommand. As far as dependencies go, I don't think you're really doing anything "bad" by raising this when the property that the command depends on changes within the ViewModel. In that case, the coupling is more or less contained wholly within the ViewModel.
So, taking your above example, in your setter for "ObjectName", you would call RaiseCanExecuteChanged on the command "AddObjectCommand".
I know this is an old question but I personally think it's easier to bind the textbox Length
to button's IsEnabled
property, e.g.:
<TextBox Name="txtbox" Width="100" Height="30"/>
<Button Content="SomeButton " Width="100" Height="30"
IsEnabled="{Binding ElementName=txtbox, Path=Text.Length, Mode=OneWay}"></Button>