从XAML设置ViewModel的属性

时间:2011-04-29 09:12:17

标签: c# wpf xaml

我有一些UserControlDataContext被绑定到ViewModel, 如何从XAML设置ViewModel的属性?有可能吗?

UPD: 对不起,不太清楚, 我想要得到这样的东西: UserControl的DataContext绑定到ViewModel,我需要将ViewModel的属性设置为某些东西(比方说,UserControl的Width属性)。 有可能吗?

UPD2:似乎不可能。我知道TwoWay绑定模式等,我想做的事情 - 将ViewModel的属性设置为UserControl的一个

这个例子应该非常清楚

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

7 个答案:

答案 0 :(得分:3)

绑定有两种方式:即从源(例如视图模型)到目标(例如用户控制)和从目标返回到源。
您可以通过Mode绑定指定方向。

以下是BindingModes

  • 双向
  • 单向
  • 一次性
  • OneWayToSource

在您的情况下,如果要将usercontrol的width属性绑定到ViewModel的TheWidth属性:

案例A:
想要双向绑定,请使用Mode = TwoWay

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

案例B:
想要仅从usercontrol绑定到viewmodel,请使用Mode = OneWayToSource

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

答案 1 :(得分:3)

我不确定我是否完全理解这个问题。

但这是一个例子。 它会:

  • 通过设置用户在用户控件中创建类型ExampleViewModel的视图模型 在xaml中控制DataContext属性

  • 在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>

视图模型:

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

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

}


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()
    {

    }
}

答案 2 :(得分:1)

XAML

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

答案 3 :(得分:1)

我更喜欢ViewModel Locator方法(这就像viewModel的服务定位器pattorn)。 因为很快你的ViewModel有构造函数参数,你要么是标题耦合,要么不能使用上面提到的xaml方式......

有许多ViewModel-Locator方法,这里使用MEF和silverlight来描述。 http://johnpapa.net/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum

这是另一个人: http://brendan.enrick.com/post/Wire-up-your-ViewModels-using-a-Service-Locator.aspx

答案 4 :(得分:0)

通过约束亲爱的朋友..

例如:(假设在您的上下文中)

如果您有“Person”类,并且您的人员具有Name和SurName公共属性,并且您希望将其绑定到文本框。您执行以下操作:

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

仅当名称是您的公共属性时才有效,最佳做法是将对象(在本例中为Person)作为公共属性并以不同方式使用Path参数。

示例:

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

它会减少您的代码混乱,然后在viewmodel中为viewmodel中的任何对象的每个属性创建一个属性。

答案 5 :(得分: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; }
}

答案 6 :(得分:-1)

“如何从XAML设置ViewModel的属性?是否可能?”

所以,这似乎是不可能的,你可以完成最大限度 - 双向绑定,不幸的是,这不是我想要的。 总而言之,这是一个相当糟糕的设计而非问题