我已经为此工作了一段时间,但似乎无法为我的问题找到任何好的答案。我正在使用具有自定义依赖属性的自定义控件,在我的主应用程序中,我使用我的 View 模型绑定(bind)到这些属性,这些属性是通过使用 mvvmlight 的 View 模型定位器看到的。我的问题是为什么绑定(bind)没有更新也没有看到正确的数据上下文?
代码:
用户控制 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>
当 This Xaml 以这种方式运行时,它会在控制台中抛出一个错误,提示它找不到 boxToEdit 或 keyboarEntry 的绑定(bind)属性,并将原始 ZKeyBoard 名称引用为找不到的位置。 . 所以我添加了这个:
<ZControls:ZKeyBoard zBoxToEdit="{Binding boxToEdit, RelativeSource={RelativeSource Mode=TemplatedParent}}" zDisplayText="{Binding keyboardEntry, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
这导致错误消失,我认为这意味着它可以找到 View 模型,但仍然没有任何反应。
最后是 View 模型:
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 正在做任何对我来说意味着它根本没有设置的事情。关于为什么这不起作用有很多大问题。对此的任何帮助都会很棒!它可能是一些小而愚蠢的东西,但第二双眼睛可能会比我更快地注意到它。
最佳答案
简单的回答:
不要将 DataContext 设置为 self。
问题已解决
关于c# - 绑定(bind)不适用于自定义用户控件的依赖属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21125271/