用户控件使用错误的DataContext [英] Usercontrol using wrong Datacontext
问题描述
我有一个在父控件使用这样一个用户控件:
<浏览次数:TranslationTextInput翻译={结合SelectedEntity.Name}/>
父控件的DataContext是包含SelectedEntity属性一个ViewModel。
在我的孩子我的UserControl定义一个新的视图模型作为DataContext的:
< UserControl.DataContext>
< VM:TranslationTextInputViewModel X:名称=VM>< / VM:TranslationTextInputViewModel>
< /UserControl.DataContext>
在code后面我有:
公共静态只读的DependencyProperty TranslationProperty = DependencyProperty.Register(翻译的typeof(翻译)的typeof(用户控件)); // .NET属性包装
公共翻译翻译
{
{返回(翻译)的GetValue(TranslationProperty); }
集合{的SetValue(TranslationProperty,值); }
}
公共TranslationTextInput(){
的InitializeComponent();
的DataContext =新TranslationTextInputViewModel();
SetBinding(TranslationProperty,新的Binding {路径=新的PropertyPath(翻译),模式= BindingMode.OneWayToSource});
在执行我得到一个绑定错误:
System.Windows.Data错误:40:BindingEx pression路径错误:'SelectedEntity'属性不是'对象'''TranslationTextInputViewModel(哈希code =发现49954236)。 BindingEx pression:路径= SelectedEntity.Name;的DataItem ='TranslationTextInputViewModel'(哈希code = 49954236);目标元素是'TranslationTextInput'(名称='InputControl'); target属性是'翻译'(类型'翻译')
看来SelectedEntity正在抬头对孩子UserControl的视图模型,而应采用父视图模型的财产。我怎样才能解决这个问题?
编辑:
公共TranslationTextInputViewModel()
{
// EnglishTranslation = tranlsations [恩];
} 公共字符串EnglishTranslation
{
得到
{
如果(!Translation.TranslationDict.ContainsKey(新的CultureInfo(EN)LCID))
Translation.Translations.Add(新TranslationItem(){文字=,LCID =新的CultureInfo(EN)LCID});
返回Translation.TranslationDict [新的CultureInfo(EN)LCID]。文本;
}
组
{
Translation.TranslationDict [新的CultureInfo(EN)LCID]。文本=价值;
} } 公共字符串SelectedTranslation
{
得到
{
如果(!Translation.TranslationDict.ContainsKey(_selectedLanguage))
Translation.Translations.Add(新TranslationItem(){文本=,LCID = _selectedLanguage});
返回Translation.TranslationDict [_selectedLanguage]。文本; } 组
{
Translation.TranslationDict [_selectedLanguage]。文本=价值;
}
} 私人翻译_translation; 公共翻译翻译
{
得到
{
如果(_translation == NULL)
_translation =新翻译();
返回_translation; }
集合{_translation =价值; }
} 私人诠释_selectedLanguage;
公众诠释SelectedLanguage
{
得到
{
返回_selectedLanguage;
}
} 公开名单<&的CultureInfo GT; AvailableLanguages
{
得到
{ 回报(从X在PqsLocalization.AvailableLanguages,其中x.Name =EN选择[x]!).ToList();
}
} 公共RelayCommand< INT> LanguageChanged {搞定;私人集; }
私人无效LanguageChangedExecute(INT郎)
{
_selectedLanguage =郎;
RaisePropertyChanged(SelectedLanguage);
RaisePropertyChanged(SelectedTranslation);
}
您真的不应该永远设置的DataContext
A 的用户控件
从里面的用户控件
。通过这样做,你是preventing任何其他的DataContext
从获得通过的用户控件
,哪一种连败WPF的最大拥有单独的用户界面和数据层的优势之一。
当正在创建的用户控件,您正在设置的DataContext
来一个新的 TranslationTextInputViewModel
和 TranslationTextInputViewModel
没有一个叫做物业 SelectedEntity
,所以你的绑定失败。
我的建议?不要设置的DataContext
在用户控件
。
如果你想使用一个特定的用户控件的特定视图模型,添加到您的 ParentViewModel
并把它作为了的DataContext
,像这样的:
< Window.Resources>
<数据类型的DataTemplate ={X:类型VM:TranslationTextInputViewModel}>
<点击:TranslationTextInput />
< / DataTemplate中>
< /Window.Resources>
或本
<浏览次数:TranslationTextInput
的DataContext ={结合SelectedTranslationTextInputViewModel}/>
或者,如果你的视图模型
包含特定于用户控件
本身的功能,而不应该是你的应用程序层的一部分,把那个code在code-背后的用户控件
和摆脱视图模型
干脆。
I have a UserControl that is used in a parent control in this way:
<Views:TranslationTextInput Translation="{Binding SelectedEntity.Name}"/>
The parent control DataContext is a ViewModel containing the SelectedEntity Property.
In my child UserControl I define a new ViewModel as the DataContext:
<UserControl.DataContext>
<vm:TranslationTextInputViewModel x:Name="vm"></vm:TranslationTextInputViewModel>
</UserControl.DataContext>
In the code behind I have:
public static readonly DependencyProperty TranslationProperty = DependencyProperty.Register("Translation", typeof(Translation),typeof(UserControl));
// .NET Property wrapper
public Translation Translation
{
get { return (Translation)GetValue(TranslationProperty); }
set { SetValue(TranslationProperty, value); }
}
public TranslationTextInput(){
InitializeComponent();
DataContext = new TranslationTextInputViewModel();
SetBinding(TranslationProperty, new Binding { Path = new PropertyPath ("Translation"), Mode = BindingMode.OneWayToSource });
When executed I get a Binding error:
System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedEntity' property not found on 'object' ''TranslationTextInputViewModel' (HashCode=49954236)'. BindingExpression:Path=SelectedEntity.Name; DataItem='TranslationTextInputViewModel' (HashCode=49954236); target element is 'TranslationTextInput' (Name='InputControl'); target property is 'Translation' (type 'Translation')
It seems the SelectedEntity is looked up on the child UserControl's Viewmodel, but the Property of the parent ViewModel should be used. How can I solve this?
Edit:
public TranslationTextInputViewModel()
{
//EnglishTranslation = tranlsations["en"];
}
public string EnglishTranslation
{
get
{
if (!Translation.TranslationDict.ContainsKey(new CultureInfo("en").LCID))
Translation.Translations.Add(new TranslationItem() { Text = "", Lcid = new CultureInfo("en").LCID });
return Translation.TranslationDict[new CultureInfo("en").LCID].Text;
}
set
{
Translation.TranslationDict[new CultureInfo("en").LCID].Text = value;
}
}
public string SelectedTranslation
{
get
{
if (!Translation.TranslationDict.ContainsKey(_selectedLanguage))
Translation.Translations.Add(new TranslationItem() { Text = "", Lcid = _selectedLanguage });
return Translation.TranslationDict[_selectedLanguage].Text;
}
set
{
Translation.TranslationDict[_selectedLanguage].Text = value;
}
}
private Translation _translation;
public Translation Translation
{
get
{
if (_translation == null)
_translation = new Translation();
return _translation; }
set { _translation = value; }
}
private int _selectedLanguage;
public int SelectedLanguage
{
get
{
return _selectedLanguage;
}
}
public List<CultureInfo> AvailableLanguages
{
get
{
return (from x in PqsLocalization.AvailableLanguages where x.Name != "en" select x).ToList();
}
}
public RelayCommand<int> LanguageChanged { get; private set; }
private void LanguageChangedExecute(int lang)
{
_selectedLanguage = lang;
RaisePropertyChanged("SelectedLanguage");
RaisePropertyChanged("SelectedTranslation");
}
You really shouldn't ever set the DataContext
of a UserControl
from inside the UserControl
. By doing so, you are preventing any other DataContext
from getting passed to the UserControl
, which kind of defeats one of WPF's biggest advantages of having separate UI and data layers.
When your UserControl is being created, you are setting the DataContext
to a new TranslationTextInputViewModel
, and TranslationTextInputViewModel
does not have a property called SelectedEntity
, so your binding fails.
My suggestion? Don't set the DataContext
in the UserControl
.
If you want a specific ViewModel to be used for a specific UserControl, add that to your ParentViewModel
and pass it in as the DataContext
, such as this:
<Window.Resources>
<DataTemplate DataType="{x:Type vm:TranslationTextInputViewModel}">
<Views:TranslationTextInput />
</DataTemplate>
</Window.Resources>
or this:
<Views:TranslationTextInput
DataContext="{Binding SelectedTranslationTextInputViewModel}" />
Or if your ViewModel
contains functionality specific to the UserControl
itself and should not be part of your application layer, put that code in the code-behind the UserControl
and get rid of the ViewModel
altogether.
这篇关于用户控件使用错误的DataContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!