【问题标题】:Setting ViewModel's Property from XAML从 XAML 设置 ViewModel 的属性
【发布时间】:2011-04-29 09:12:17
【问题描述】:

我有一些UserControl,它的DataContext绑定到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}>

【问题讨论】:

  • 考虑到您发布的伪 XAML,为什么 不适合您?您到底想实现什么(从更大的角度来看)?
  • 我想在 UserControl 上确定属性时使用绑定,例如在伪 xaml 中
  • 你可以绑定到所有你想要的 DependencyProperties。因此,如果您的 UserControl 有任何 DependencyProperties,您可以绑定到它。
  • 需求(或者更确切地说是需要)仍然不清楚。您是否要在特定事件上设置 SomePropertyOnViewModel 的值?你能发布更多关于你想要实现的代码吗?

标签: c# wpf xaml


【解决方案1】:

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

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

  • 通过设置用户在用户控件内创建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】:

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

    以下是BindingModes

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

    在您的情况下,如果您想将用户控件的宽度属性绑定到 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>
    

    【讨论】:

    • 是的,我认为这是用于 silverlight,在 wpf 中,你有 onewaytosource 这是正确的答案
    【解决方案3】:

    XAML

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

    【讨论】:

    • OK 这会将 UserControl 的 DataContext 设置为 new ViewModel(),所以...?
    【解决方案4】:

    我更喜欢 ViewModel Locator 方法(这类似于 ViewModel 的服务定位器模式)。 因为一旦你的 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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

      • 这段代码将 UserControl 中的某些内容绑定到 ViewModel 中的某些内容,问题是,我需要反之亦然
      • 那么就可以使用 Text="{Binding MyProperty, Mode=OneWayToSource}"
      • 不,Text 不是 ViewModel 的属性,请参阅我在 UPD 中的描述
      【解决方案6】:

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

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

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

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

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

      例子:

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

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          猜你喜欢
          • 2011-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-03
          相关资源
          最近更新 更多