2012-07-06 101 views
1

我在WPF中建立了一個自定義的UserControl,它具有一個ViewModel關聯。我也想動態地在代碼背後進行控制。但現在我遇到了將生成的控件與ViewModel屬性綁定的問題。我的代碼是:WPF在ViewModel後面的代碼綁定動態控制

<UserControl x:Class="SVT.Teste.UserControl1" 
      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" 
      d:DesignHeight="300" d:DesignWidth="300" 
      DataContext="UserControl1ViewModel"> 
    <Grid Name="GridContainer"> 
    </Grid> 
</UserControl> 

和後面的代碼:

public UserControl1() 
    { 
     InitializeComponent(); 
     System.Windows.Controls.Button newBtn = new Button(); 
     newBtn.SetBinding(Button.ContentProperty, new Binding("Test")); 
     GridContainer.Children.Add(newBtn); 
    } 

    public class UserControl1ViewModel 
    { 
     private string test = "ola"; 

     public string Test 
     { 
      get { return test; } 
     } 
    } 

當我運行此我得到:

"System.Windows.Data Error: 40 : BindingExpression path error: 'Test' property not found on 'object' ''String' (HashCode=-946585093)'. BindingExpression:Path=Test; DataItem='String' (HashCode=-946585093); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')"

你能幫助我嗎?

回答

2

您的UserControl1DataContext屬性設置爲一個字符串,而不是您的視圖模型實例。

你需要做這樣的事情:

<UserControl xmlns:local="clr-namespace:NAMESPACE_WHERE_VIEWMODEL_IS_DEFINED"> 
    <UserControl.DataContext> 
     <local:UserControl1ViewModel /> 
    </UserControl.DataContext> 
    <!-- unrelated code omitted --> 
</UserControl> 
+0

儘管所有的答案都有效,但這對我來說是正確的答案,因爲我有一個View第一種方法,我不喜歡在後面的代碼中設置數據綁定。非常感謝你! – Louro 2012-07-06 07:45:05

1

嘗試這種結合

Binding MyBinding = new Binding(); 
MyBinding.Path = new PropertyPath("Test"); 
newBtn.DataContext = new UserControl1ViewModel(); //or MyBinding.Source = new //UserControl1ViewModel(); 


newBtn.SetBinding(Button.ContentProperty, MyBinding); 
2

你是你的DataContext設置的類型,不具有該特性的實例。 在你的方法是創建用戶控制做到:

  public UserControl1() 
     { 
      InitializeComponent(); 
      System.Windows.Controls.Button newBtn = new Button(); 
      newBtn.SetBinding(Button.ContentProperty, new Binding("Test")); 
      GridContainer.Children.Add(newBtn); 
      **DataContext = new UserControl1ViewModel();** 
     } 

你還有更多的工作要做。你有沒有通知或更新的方式會發生。實施INotifyPropertyChanged接口(在UserControlViewModel上)。並將XAML中的設置DataContext刪除爲該類型。

0

max是正確的,但我有另一個問題。爲什麼你想要創建你的usercontrol動態當你有一個viemwodel你想綁定?對我沒有意義。讓我解釋一下:

如果你有一個視圖模型 - 你知道這個視圖模型應該如何呈現以及綁定是什麼。所以你可以爲這個視圖模型

MyUserControl1View.xaml

<UserControl> 
<Grid> 
    <Button Content="{Binding Test}"/> 
    <!-- more controls and binding if the viewmodel expose more--> 
</Grid> 
</UserControl> 

所以你現在有什麼是您的視圖模型的表示創建一個用戶控件/視圖。它們不是連接的,但你的視圖模型應該看起來像這樣並且綁定被設置。直到現在還沒有設置datacontext。

現在你所要做的就是採用viewmodel的第一種方法和數據模型的使用。

讓我們假設你的主窗口下面

<Window> 
<Window.Resources> 
    <DataTemplate Datatype="{x:Type local:Usercontrol1viewmodel}"> 
    <view:MyUserControl1View/> 
    </DataTemplate> 
</Window.Resources> 

現在WPF如何呈現Usercontrol1viewmodel。

您在處理Usercontrol1viewmodel的主窗口視圖模型中多了一步。

public Usercontrol1viewmodel MyWhatEver {get;set;} 

如果此屬性綁定到contentpresenter,你會看到WPF魔術;)

<ContentPresenter Content="{Binding MyWhatEver}"/> 

現在你看到contentpresenter的MyUserControl1View,沒有動態視圖代碼需要。隨你的viewmodels去。

ps:隨時編輯我的壞英語。

+0

在我的問題中,我只是解釋了一個簡單的例子。事情是,我有一個項目列表,有一個字段列表。這個字段列表是動態的。我遍歷字段的列表,爲每個創建一個組合框或一個文本塊,並將其綁定到ViewModel - 我仍然在考慮如何做最後一部分。感謝您的專注;) – Louro 2012-07-06 07:51:19

+0

np,當你寫字段是動態的 - 你是否真的意味着對象(具有屬性的viewmodel)沒有在設計時定義?只要你有一個明確的類型,你可以輕鬆地與我的問題一起走。我不得不說我真的不喜歡MVVM(除了應用程序根/主窗口)的「視圖優先」方法 – blindmeis 2012-07-06 08:19:31

+0

我已經詳細闡述了自己的問題(因爲問題是從設計的角度而不是實現作爲這一個)在這裏: http://stackoverflow.com/questions/11358669/wpf-dynamic-controls-in-view-and-viewmodel – Louro 2012-07-06 08:36:32