Reputation: 43
I'm using MVVMCross in my crossplatform native Xamarin app. I seem to have a problem binding boolean properties in my custom control to boolean properties in my ViewModel. For example:
My custom control BarCodeTextBox.cs:
public sealed class BarCodeTextBox : TextBox
{
public BarCodeTextBox()
{
this.DefaultStyleKey = typeof(BarCodeTextBox);
}
public bool IsListeningForCodes
{
get { return (bool)GetValue(IsListeningForCodesProperty); }
set {
SetValue(IsListeningForCodesProperty, value);
if (value)
{
IsReadOnly = true;
PrefixElement.Visibility = Visibility.Collapsed;
Window.Current.CoreWindow.CharacterReceived += CoreWindow_CharacterReceived;
}
else
{
IsReadOnly = false;
Focus(FocusState.Keyboard);
PrefixElement.Visibility = Visibility.Visible;
Window.Current.CoreWindow.CharacterReceived -= CoreWindow_CharacterReceived;
}
Text = string.Empty;
}
}
// Using a DependencyProperty as the backing store for IsListening. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsListeningForCodesProperty =
DependencyProperty.Register("IsListeningForCodes", typeof(bool), typeof(BarCodeTextBox), new PropertyMetadata(false));
The viewmodel of the page BoxCloseViewModel.cs:
public class BoxCloseViewModel : ViewModelBase
{
private bool m_isManualBoxCodeInput;
public bool IsManualBoxCodeInput
{
get { return m_isManualBoxCodeInput; }
set { SetProperty(ref m_isManualBoxCodeInput, value); }
}
}
The binding in BoxCloseView.xaml:
<Controls:BarCodeTextBox x:Name="BarCodeInput" Text="{Binding BoxCode, Mode=TwoWay}" IsListeningForCodes="{Binding IsManualBoxCodeInput, Mode=OneWay, Converter={StaticResource BoolToInverseBool}}"/>
When I change the value of IsManualBoxCodeInput in the ViewModel nothing happens in the control (IsListeningForCodes does not change). Things I checked:
Upvotes: 1
Views: 901
Reputation: 71936
Bindings don't call the setter property of a DependencyObject
. If you want some code to execute when a binding changes you need to add it as a callback of the PropertyMetadata
.
public bool IsListeningForCodes
{
get { return (bool)GetValue(IsListeningForCodesProperty); }
set { SetValue(IsListeningForCodesProperty, value); }
}
public static readonly DependencyProperty IsListeningForCodesProperty =
DependencyProperty.Register("IsListeningForCodes", typeof(bool), typeof(BarCodeTextBox),
new PropertyMetadata(false, OnIsListeningForCodesChanged));
static void OnIsListeningForCodesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var instance = (BarCodeTextBox)d;
instance.OnIsListeningForCodesChanged();
}
void OnIsListeningForCodesChanged()
{
if (IsListeningForCodes)
{
IsReadOnly = true;
PrefixElement.Visibility = Visibility.Collapsed;
Window.Current.CoreWindow.CharacterReceived += CoreWindow_CharacterReceived;
}
else
{
IsReadOnly = false;
Focus(FocusState.Keyboard);
PrefixElement.Visibility = Visibility.Visible;
Window.Current.CoreWindow.CharacterReceived -= CoreWindow_CharacterReceived;
}
Text = string.Empty;
}
Upvotes: 2