簡體   English   中英

通過MVVM模式創建UserControl - DataContext並綁定到父級

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM