简体   繁体   中英

Binding is not working on custom user control's dependency property

I've been working at this for awhile and seeming to not be able to find any good answers to my problem. I'm using a custom control that has custom dependency properties and in my main app I am binding to those propertys with my viewmodel that is seen through a viewmodel locator using mvvmlight. my question is why is the binding not updating nor seeing the correct datacontext?

Code:

User Control 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>

Things I have Tried In The User Control Xaml Already:

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

User Control 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(""));
}

}

Things I have already tried in the user control C#:

public string zBoxToEdit
    {
        get;
        set;
    }

public string zDisplayText
    {
        get;
        set;
    }

Here is the Project Files Where the User Control Is Being Used:

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>

The ViewModel Locator:

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
    }
}

}

The Xaml The User Control Is Being Used In:

<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>

When This Xaml is ran as is This Way It Throws an error in the console that says it can not find the binding property of either boxToEdit or keyboarEntry and it refrences the original ZKeyBoard Name as The place it can not be found... So I added this:

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

Which caused the error to go away which I assume meant that it could find the viewmodel yet still nothing happened.

And Finally The View Model:

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);
            }
        }
    }

}

}

One Thing I noticed was that I can Not See The Console.out.writeline doing anything which to me means it is not setting at all. so lots of big questions as to why this is not working. Any Help on this would be amazing! it probably is something small and stupid but a second pair of eyes on this will probably notice it faster than me.

Simple answer:

Don't set the DataContext to self.

Problem resolved

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM