简体   繁体   English

将自定义控件中的DependencyProperty绑定到ViewModel属性

[英]Binding DependencyProperty in custom control to ViewModel property

I'm using MVVMCross in my crossplatform native Xamarin app. 我在跨平台的本地Xamarin应用程序中使用MVVMCross。 I seem to have a problem binding boolean properties in my custom control to boolean properties in my ViewModel. 我似乎在将自定义控件中的布尔属性绑定到ViewModel中的布尔属性时遇到问题。 For example: 例如:

My custom control BarCodeTextBox.cs: 我的自定义控件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: 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: 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). 当我在ViewModel中更改IsManualBoxCodeInput的值时,控件中没有任何反应(IsListeningForCodes不会更改)。 Things I checked: 我检查过的事情:

  • The converter works perfectly (and removing it does not solve the issue). 转换器工作正常(将其删除并不能解决问题)。 In fact the converter is called when the ViewModel property changes (I'm able to debug it). 实际上,当ViewModel属性更改时,将调用该转换器(我可以对其进行调试)。
  • When I change the value of IsListeningForCodes in the page's code behind, it works (the control shows the change). 当我在后面的页面代码中更改IsListeningForCodes的值时,它可以工作(控件显示更改)。
  • When I do the exact same thing with a string property, everything works perfectly. 当我使用字符串属性执行完全相同的操作时,一切都将正常运行。
  • There are no binding errors in the Output log. 在输出日志中没有绑定错误。
  • PropertyChangedEvent is fired correctly with IsManualBoxCodeInput property. 使用IsManualBoxCodeInput属性可以正确触发PropertyChangedEvent。
  • I've realized the same thing happened to another control with a boolean property which used to work, after migrating to MVVMCross no longer does. 在迁移到MVVMCross后,我已经意识到另一个具有布尔属性的控件也发生了同样的事情,该属性过去一直有效。

Bindings don't call the setter property of a DependencyObject . 绑定不会调用DependencyObject的setter属性。 If you want some code to execute when a binding changes you need to add it as a callback of the PropertyMetadata . 如果要在绑定更改时执行某些代码,则需要将其添加为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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 公开一个ViewModel事件以绑定到自定义DependencyProperty - Expose a ViewModel event for binding to a custom DependencyProperty 将 ControlTemplate 子项绑定到自定义控件上的 DependencyProperty 不起作用 - Binding ControlTemplate child to DependencyProperty on a custom control not working 将 ToolTip 绑定到自定义控件内的 DependencyProperty - Binding ToolTip to DependencyProperty inside custom control 在自定义用户控件的DependencyProperty上绑定不更新更新 - Binding on DependencyProperty of custom User Control not updating on change 绑定依赖项属性-在自定义用户控件中设置,在viewmodel中获取 - Binding dependency property - set in custom user control, get in viewmodel 将控件的样式绑定到 Viewmodel 属性 - Binding the style of the control to a Viewmodel property 绑定未更新UserControl的ViewModel的DependencyProperty - DependencyProperty on ViewModel of UserControl not updated by Binding WPF从ViewModel绑定到DependencyProperty - WPF Binding to DependencyProperty from ViewModel 将CustomControl DependencyProperty绑定到ViewModel枚举 - Binding a CustomControl DependencyProperty to a ViewModel enum 绑定到用户控件中的依赖属性并在嵌套属性更改时调用 CanExecute - Binding to dependencyproperty in user control and calling CanExecute on nested property change
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM