绑定不适用于自定义用户控件的依赖项属性

时间:2014-01-14 22:23:19

标签: c# wpf mvvm binding user-controls

我已经在这工作了一段时间,似乎无法找到任何问题的好答案。我正在使用具有自定义依赖项属性的自定义控件,在我的主应用程序中,我使用mvvmlight通过viewmodel定位器查看的viewmodel绑定到那些属性。我的问题是为什么绑定没有更新也没有看到正确的datacontext?

代码:

用户控制Xaml:

<UserControl x:Name="zKeyBoard"
         x:Class="ZLibrary.ZKeyBoard"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d"
         DataContext="{Binding RelativeSource={RelativeSource Self}}"
         d:DesignHeight="768" d:DesignWidth="1024">
<Grid>
    <TextBox TextWrapping="Wrap" Text="{Binding zDisplayText}" />
    <Label Content="{Binding zBoxToEdit}"/>
</Grid>
</UserControl>

我已经在用户控件Xaml中尝试过的事情:

<TextBox TextWrapping="Wrap" Text="{Binding zDisplayText, ElementName=zKeyBoard}" />
<Label Content="{Binding zBoxToEdit, ElementName=zKeyBoard}"/>

用户控制C#:

using System.ComponentModel;

namespace ZLibrary
{

public partial class ZKeyBoard : UserControl, INotifyPropertyChanged
{

    public ZKeyBoard()
    {
        InitializeComponent();
    }

 public string zBoxToEdit
    {
        get { return (string)GetValue(zBoxToEditProperty); }
        set { SetValue(zBoxToEditProperty, value); }
    }

    public static readonly DependencyProperty zBoxToEditProperty =
        DependencyProperty.Register("zBoxToEdit", typeof(string), typeof(ZKeyBoard), new UIPropertyMetadata(""));

public string zDisplayText
    {
        get { return (string)GetValue(zDisplayTextProperty); }
        set { SetValue(zDisplayTextProperty, value); }
    }

    public static readonly DependencyProperty zDisplayTextProperty =
        DependencyProperty.Register("zDisplayText", typeof(string), typeof(ZKeyBoard), new UIPropertyMetadata(""));
}

}

我在用户控件C#中尝试过的事情:

public string zBoxToEdit
    {
        get;
        set;
    }

public string zDisplayText
    {
        get;
        set;
    }

以下是使用用户控件的项目文件:

的App.xaml:

<Application x:Class="WpfApplication1.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:vm="clr-namespace:Sandstorm.ViewModel" 
         mc:Ignorable="d"
         StartupUri="Main.xaml">
<Application.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </ResourceDictionary>
</Application.Resources>
</Application>

ViewModel定位器:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;

namespace Sandstorm.ViewModel
{
class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<KeyBoardViewModel>(() =>
        {
            return new KeyBoardViewModel();
        });
    }

    public KeyBoardViewModel KeyBoardViewModel 
    { 
        get { return ServiceLocator.Current.GetInstance<KeyBoardViewModel>(); } 
    }

    public static void Cleanup()
    {
        // TODO Clear the ViewModels
    }
}

}

Xaml正在使用用户控件:

<Page x:Name="keyboard_Frame"
  x:Class="Sandstorm.keyBoard"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:ZControls="clr-namespace:ZLibrary;assembly=ZLibrary"
  DataContext="{Binding KeyBoardViewModel, Source={StaticResource Locator}}"
   mc:Ignorable="d" 
  d:DesignHeight="768" d:DesignWidth="1024"
  ShowsNavigationUI="False"
Title="KeyBoard">
<Grid>
    <ZControls:ZKeyBoard zBoxToEdit="{Binding boxToEdit}" zDisplayText="{Binding keyboardEntry}" />
</Grid>
</Page>

当这个Xaml按原样运行时它会在控制台中输出一个错误,指出它无法找到boxToEdit或keyboarEntry的绑定属性,并且它将原始的ZKeyBoard名称引用为无法找到的位置。所以我补充说:

<ZControls:ZKeyBoard zBoxToEdit="{Binding boxToEdit, RelativeSource={RelativeSource Mode=TemplatedParent}}" zDisplayText="{Binding keyboardEntry, RelativeSource={RelativeSource Mode=TemplatedParent}}" />

导致错误消失,我认为这意味着它可以找到视图模型但仍然没有发生任何事情。

最后是视图模型:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.ComponentModel;

namespace Sandstorm.ViewModel
{

class KeyBoardViewModel : ViewModelBase, INotifyPropertyChanged
{
    private string _keyboardEntry;
    private string _boxToEdit;

 public KeyBoardViewModel()
    {
        _boxToEdit = "yay";
    }

public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

public string keyboardEntry
    {
        get { return this._keyboardEntry; }
        set
        {
            if (this._keyboardEntry != value)
            {
                this._keyboardEntry = value;
                this.OnPropertyChanged("keyboardEntry");
                Console.Out.WriteLine(this._keyboardEntry);
            }
        }
    }

    public string boxToEdit
    {
        get { return this._boxToEdit; }
        set
        {
            if (this._boxToEdit != value)
            {
                this._boxToEdit = value;
                this.OnPropertyChanged("boxToEdit");
                Console.Out.WriteLine(this._boxToEdit);
            }
        }
    }

}

}

我注意到的一件事是我无法看到Console.out.writeline做任何事情对我来说意味着它根本没有设置。关于为什么这不起作用的许多重大问题。对此的任何帮助都会很棒!它可能是一个小而愚蠢的东西,但第二双眼睛可能会比我更快注意到它。

1 个答案:

答案 0 :(得分:4)

简单回答:

不要将DataContext设置为self。

问题已解决