[英]Creating UserControl via MVVM pattern - DataContext and binding to parent
我使用MVVM模式,所以我自己的控件包含View和ViewModel。
ViewModel與View by DataContext屬性相關聯。 這會產生綁定問題。 為什么?
假設這種情況:
我創建了新的用戶控件 - 例如 - “SuperTextBox”。 它有一個屬性“SuperValue”。
現在我做了類似的事情:
<Window>
<Window.DataContext>
<vm:WindowViewModel/>
</Window.DataContext>
<local:SuperTextBox SuperValue="{Binding Test}"/>
</Window>
我認為“綁定進程”將SuperTextBox.SuperValue與Window.DataContext.Test連接起來,但是沒有,“綁定進程”將SuperTextBox.SuperValue與SuperTextBox.DataContext.Test連接起來對我來說不自然和誤導。
像TextBox這樣的其他控件我可以用上面的方式,因為它們沒有DataContext。
如何使用MVVM模式創建保持自然綁定的UserControl(對於父控件的DataContext)?
編輯:
我得到了許多答案,如何綁定父母,但我早先知道。 問題是 - 如何通過MVVM patern(具有ViewModel)創建UserControl並保持自然綁定 - 默認為父DataContext。
我想擁有ViewMoldel,仍然可以像這樣綁定:
<local:SuperTextBox SuperValue="{Binding Test}"/>
可能嗎?
應用於任何control always first look for the binding in its DataContext
所有綁定control always first look for the binding in its DataContext
。 如果未為控件設置DataContext,則它會將walks up the Visual Tree
到其父級,除非它找到DataContext。
即使您將textBox上的DataContext
設置為與Window的DatContext不同的某個值,它也將始終在該特定DataContext上搜索屬性Test
,而不是在Window's DataContext
。
<TextBox>
<TextBox.DataContext>
<vm:ViewModelForTextBox/>
</TextBox.DataContext>
<TextBox.Text>
<Binding Path="Test"/>
</TextBox.Text>
</TextBox>
現在,xaml將在類ViewModelForTextBox
查找Test
屬性,而不是在WindowViewModel
類中查找,如果在ViewModelForTextBox
類中找不到Test
屬性, binding will fail silently
並且不會查找Window的DataContext類。
如果您仍想為自定義UserControl設置DataContext但仍希望綁定到父級(Window)dataContext,則必須在綁定中使用RelativeSource MarkupExtension
,如下所示 -
<local:SuperTextBox SuperValue="{Binding Path=DataContext.Test,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}">
有關更多說明,請參閱此處的MSDN文章。
你應該發布你的SuperTextBox代碼,因為你的錯誤。
通常你創建一個帶有依賴屬性的usercontrol - 在你的情況下是“SuperValue” - 現在最重要的是你沒有將SuperTextBox的datacontext設置為自己。
你必須在你的SuperTextBox中使用elementname綁定來綁定到“SuperValue”
<SuperTextBox x:Name="uc">
<TextBox Text="{Binding ElementName=uc, Path=SuperValue}/>
</superTextBox>
如果你這樣做 - 你的
<local:SuperTextBox SuperValue="{Binding Test}"/>
應該工作,並應綁定到您的vm:WindowViewModel的測試屬性。 這是編寫如上所述的綁定的唯一方法。
編輯:如果你想為你的usercontrol創建一個viewmodel,那就說SuperTextViewmodel。 然后它會有一個屬性“SuperValue”。 現在你不能設置datacontext兩次所以我建議你必須在你的WindowTem模型中添加一個屬性SuperTextViewmodel並處理你想要的屬性。
你的綁定看起來像這樣
<local:SuperTextBox DataContext="{Binding MySuperTextViewmodelInstanceOnWindowViewmodel}"/>
我會回答我的第一部分答案:)我總是說一個視圖需要一個viewmodel但是一個usercontrol依賴屬性。
你需要“查找”它的窗口祖先的datacontext。 你的綁定看起來像這樣:
<local:SuperTextBox SuperValue="{Binding Path=DataContext.Test, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
我覺得奇怪地回答我的問題,但......
在我自己的控制下,我做了類似的事情:
<UserControl>
<Grid>
<Grid.DataContext>
<vm:UserControlViewModel />
</Grid.DataContext>
// here realy code of control
</Grid>
</UserControl>
現在我可以在控制之外和控制之外使用“自然”綁定。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.