从 XAML 设置 ViewModel 的属性

发布于 2024-11-04 02:00:42 字数 544 浏览 1 评论 0原文

我有一些 UserControl,它的 DataContext 绑定到 ViewModel, 如何从 XAML 设置 ViewModel 的属性?是否可以?

更新: 抱歉不太清楚, 我正在尝试得到这样的东西: UserControl 的 DataContext 绑定到 ViewModel,我需要将 ViewModel 的属性设置为某些内容(比方说,UserControl 的 Width 属性)。 是否可以?

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

这个示例应该非常清楚

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

I have some UserControl, It's DataContext is binded to the ViewModel,
How to set a ViewModel's property from XAML? Is it possible?

UPD :
Sorry for being not very clear,
I'm trying to get something like this :
UserControl's DataContext is binded to ViewModel, I need to set ViewModel's property to something (let's say, UserControl's Width property).
Is it possible?

UPD2: It seems to be not possible.I know about TwoWay binding mode, etc, thing I wanted to do - to set ViewModel's property to UserControl's one

This example should be very clear

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

暮年 2024-11-11 02:00:42

我不确定我是否准确理解了这个问题。

但这里有一个例子。
它将:

  • 通过设置用户在用户控件内创建一个 ExampleViewModel 类型的视图模型
    control 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>

ViewModel:

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

    }
}

I am not sure whether I understand the question exactly.

But here is an example.
It will:

  • Create a view model of type ExampleViewModel inside the user control by setting the user
    controls DataContext property in xaml

  • Create a text box in xaml and bind it to the view models
    TextInViewModel string property.

  • Set up the usual INotifyPropertyChanged interface (this was extracted to the base class ViewModelBase)

Create the view model in xaml and set the user controls data context to it:

<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));
        }
    }

}


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

    }
}
在你怀里撒娇 2024-11-11 02:00:42

绑定是双向的:即从源(例如视图模型)到目标(例如用户控件)以及从目标回到源。

您可以通过模式指定方向绑定。

以下是 BindingModes

  • TwoWay
  • OneWay
  • OneTime
  • OneWayToSource

在您的情况下,如果您想将用户控件的 width 属性绑定到 ViewModel 的 TheWidth 属性:

情况 A:

想要双向绑定,请使用Mode=TwoWay

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

情况B:

只想从用户控件绑定到视图模型,请使用 Mode=OneWayToSource

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

Binding works both ways: i.e. from source (e.g. viewmodel) to target (e.g. usercontrol) and from target back to source.


You specify the direction via Mode of binding.



Following are the BindingModes:

  • TwoWay
  • OneWay
  • OneTime
  • OneWayToSource

In your case, if you want to bind width property of usercontrol to the TheWidth property of ViewModel:

Case A:


Want to bind in both directions, use Mode=TwoWay

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

Case B:


Want to bind only from usercontrol to viewmodel, use Mode=OneWayToSource

<UserControl Width="{Binding TheWidth, Mode=OneWayToSource}">
<!-- your rest of code -->
</UserControl>
嗫嚅 2024-11-11 02:00:42

XAML

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

XAML

   <UserControl.DataContext>
        <vm:ViewModel/>
    </UserControl.DataContext>
江湖正好 2024-11-11 02:00:42

我更喜欢 ViewModel 定位器方法(这就像 ViewModel 的服务定位器模式)。
因为一旦你的 ViewModel 有了构造函数参数,你要么是紧密耦合的,要么就不能使用上面描述的 xaml 方式......

有很多 ViewModel-Locator 方式。此处使用 MEF 和 silverlight 描述了一种。
http://johnpapa.net/ simple-viewmodel-locator-for-mvvm-the-患者-have-left-the-asylum

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

I prefer the ViewModel Locator approach (this is like a service locator pattern for ViewModel).
Because as soon as your ViewModel has constructor parameters, you are either tightly coupled, or you can't use the above described xaml way....

There are many ViewModel-Locator ways. One is described here using MEF and silverlight.
http://johnpapa.net/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum

here is another one:
http://brendan.enrick.com/post/Wire-up-your-ViewModels-using-a-Service-Locator.aspx

云醉月微眠 2024-11-11 02:00:42

好吧,您将 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; }
}

Well, you bind your UI elements to them:

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

assuming a view model like this:

class ViewModel
{
    public string MyProperty { get; set; }
    public int DisplayWidth { get; set; }
}
杀お生予夺 2024-11-11 02:00:42

通过绑定我亲爱的朋友..

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

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

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

这只适用于名称是您的公共属性的情况,最佳实践是使您的对象(在本例中为 Person)作为公共属性并以不同的方式使用 Path 参数。

示例:

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

它确实可以减少代码的混乱程度,然后在视图模型中为视图模型中任何对象的每个属性创建一个属性。

Through binding my dear friend..

for example: (Assuming in your context)

If you have class "Person" and your person has a Name and SurName public property and you want to bind it to a textbox. You do the following:

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

This only works if the name is your public property, it is best practice to make you object ( in this case Person) as a public property and use the Path parameter differently.

Example:

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

It does clutter your code way less, then to make a property in your viewmodel for every property of any object in your viewmodel.

影子是时光的心 2024-11-11 02:00:42

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

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

"How to set a ViewModel's property from XAML? Is it possible?"

So, that seems to be not possible, max you can accomplish - two-way binding, which is, unfortunately not I wanted.
All in all it's rather bad design than a problem

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文