2011-04-29 80 views
2

我有一些UserControl,它的DataContext綁定到ViewModel, 如何設置ViewModel的屬性從XAML?可能嗎?設置ViewModel的屬性從XAML

UPD: 對不起,我是不是很清楚, 我想要得到的東西是這樣的: 用戶控件的DataContext的被綁定到視圖模型,我需要視圖模型的屬性設置的東西(比方說,用戶控件的寬度屬性)。 這可能嗎?

UPD2:這似乎是不possible.I瞭解雙向綁定模式,等等,事情我想做的事 - 設置視圖模型的財產,以用戶控件的一個

這個例子應該很清楚

<Set Property={Binding SomePropertyOnViewModel} 
    Value={Binding RelativeSource={RelativeSource Self}, 
        Path=SomePropertyOnUserControl}> 
+0

考慮到您的僞XAML發佈,爲什麼沒有爲你工作?你想達到什麼目的(從更大的角度來看)? – publicgk 2011-04-29 10:39:44

+0

我想在確定UserControl屬性時使用綁定,就像在pseudo-xaml – 2011-04-29 11:41:07

+0

中一樣,您可以綁定到所需的所有DependencyProperties。所以如果你的UserControl有任何的DependencyProperties你可以綁定到它。 – blindmeis 2011-04-29 13:04:58

回答

-1

所以,這似乎是不可能的,最大你可以完成 - 雙向綁定,這是,不幸的是不是我想要的。 總而言之,這是相當糟糕的設計比問題

1

XAML

<UserControl.DataContext> 
     <vm:ViewModel/> 
    </UserControl.DataContext> 
+0

好吧,這將設置UserControl的DataContext到新的ViewModel(),所以...? – 2011-04-29 09:33:06

+0

你想做什麼? – PawelSt 2011-04-29 09:37:13

+0

更新我的問題 – 2011-04-29 09:49:25

0

通過結合我親愛的朋友..

例如:(假設在你的上下文中)

如果你有類「人」,你的人有一個名稱和SurName公共屬性,你想要將它綁定到一個文本框。你做到以下幾點:如果

這隻作品中的名字是你的公共財產,它是讓你反對的最佳實踐(在這種情況下,人)作爲公共財產和不同的使用Path參數。

例子:

<TextBox Text="{Binding Path=Person.Name}" /> 

它確實混亂的編碼方式少,然後在您的視圖模型屬性在您的視圖模型的任何對象的每個屬性。

0

嗯,你綁定你的UI元素對他們說:

<UserControl Width="{Binding Path=DisplayWidth, Mode=OneWayToSource}"> 
    <Grid> 
     <TextBox MinWidth=100 Text="{Binding MyProperty}"/> 
    </Grid> 
</UserControl> 

假設這樣的視圖模型:

class ViewModel 
{ 
    public string MyProperty { get; set; } 
    public int DisplayWidth { get; set; } 
} 
+0

此代碼將UserControl的某些內容綁定到ViewModel中的某個東西,問題是,我需要將它反過來 – 2011-04-29 09:51:19

+0

然後,您可以使用Text =「{Binding MyProperty,Mode = OneWayToSource}」 – PVitt 2011-04-29 09:58:45

+0

否,文本不是一個ViewModel的屬性,請參閱我的描述,在UPD – 2011-04-29 10:03:24

3

綁定是雙向的:從源代碼IE瀏覽器(如視圖模型)的目標(例如用戶控制)和從目標回到源。
指定通過Mode綁定的方向。

以下是BindingModes

  • 雙向
  • 單向
  • 一次性
  • OneWayToSource

在你的情況,如果你想用戶控件的寬度屬性綁定到TheWidth ViewModel的性質:

例A:
要在兩個方向上結合,使用模式=雙向

<UserControl Width="{Binding TheWidth, Mode=TwoWay}"> 
<!-- your rest of code --> 
</UserControl> 

情況B:
想僅從用戶控件結合視圖模型,使用模式= OneWayToSource

<UserControl Width="{Binding TheWidth, Mode=OneWayToSource}"> 
<!-- your rest of code --> 
</UserControl> 
+0

是的,我認爲這是Silverlight,在WPF,你有onewaytosource這是正確的答案 – 2011-04-29 10:15:52

1

我更喜歡ViewModel Locator方法(這就像服務定位器pattorn對於viewModels)。 因爲一旦你AUS竟視圖模型參數的構造函數你要麼titly加上或無法使用上述XAML的方式....

有一個多視圖模型 - 定位方法之一,這裏discribed使用MEF和Silverlight。 http://johnpapa.net/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum

這裏是anotherone: 「?如何從XAML設置視圖模型的財產是否有可能」 http://brendan.enrick.com/post/Wire-up-your-ViewModels-using-a-Service-Locator.aspx

3

我不知道我是否完全理解問題。

但這裏是一個例子。 它會:

  • 通過設置用戶 控制在XAML DataContext屬性創建用戶控件中ExampleViewModel類型的視圖模型

  • XAML中創建一個文本框,並將其綁定到視圖模型 TextInViewModel字符串屬性。

  • 設置通常的INotifyPropertyChanged界面(此萃取基類ViewModelBase

XAML創建視圖模型,並設置用戶控制數據上下文它:

<UserControl x:Class="MyUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="Test" 
      xmlns:viewModel="clr-namespace:ViewModels"> 
     <UserControl.DataContext> 
      <viewModel:ExampleViewModel/> 
     </UserControl.DataContext> 

     <StackPanel Orientation="Horizontal" > 
      <Label>Enter Text here: </Label> 
      <TextBox Text="{Binding TextInViewModel}"></TextBox> 
     </StackPanel> 
</UserControl> 

ViewModel:

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public void RaisePropertyChanged(string prop) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(prop)); 
     } 
    } 

    #endregion 
} 


public class ExampleViewModel : ViewModelBase 
{ 
    /// <summary> 
    /// Property bound to textbox in xaml. 
    /// </summary> 
    public String TextInViewModel 
    { 
     get { return _textInViewModel; } 
     set 
     { 
      _textInViewModel= value; 
      RaisePropertyChanged("TextInViewModel"); 
     } 
    } 
    private string _textInViewModel; 

    /// <summary> 
    /// Constructor. 
    /// </summary> 
    public ExampleViewModel() 
    { 

    } 
}