1

我正在 WPF 中构建一个自定义 UserControl,它具有关联的 ViewModel。我还想在后面的代码中动态制作控件。但是现在我在将生成的控件与 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 错误:40:BindingExpression 路径错误:在 'object' ''String' (HashCode=-946585093) 上找不到 'Test' 属性。BindingExpression:Path=Test; DataItem='String' (HashCode= -946585093); 目标元素是'Button' (Name=''); 目标属性是'Content' (类型'Object')"

你能帮助我吗?

4

4 回答 4

2

您正在将DataContext属性设置UserControl1为字符串而不是视图模型实例。

你需要做这样的事情:

<UserControl xmlns:local="clr-namespace:NAMESPACE_WHERE_VIEWMODEL_IS_DEFINED">
    <UserControl.DataContext>
        <local:UserControl1ViewModel />
    </UserControl.DataContext>
    <!-- unrelated code omitted -->
</UserControl>
于 2012-07-06T07:26:33.233 回答
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接口(on UserControlViewModel)。并删除类型DataContext中的设置XAML

于 2012-07-06T07:32:52.007 回答
1

尝试使用此绑定

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


newBtn.SetBinding(Button.ContentProperty, MyBinding);
于 2012-07-06T07:23:46.933 回答
0

max 是对的,但我还有一个问题。当您有要绑定的 viemwodel 时,为什么要创建用户控件动态?对我来说没有意义。让我解释:

如果你有一个视图模型——你知道应该如何渲染这个视图模型以及绑定是什么。所以你可以为这个视图模型创建一个用户控件/视图

MyUserControl1View.xaml

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

所以你现在拥有的是你的视图模型的表示。它们没有连接,但您的视图模型应该看起来像这样并且绑定已设置。到目前为止,根本没有设置任何数据上下文。

您现在要做的就是采用视图模型优先方法并使用数据模板。

让我们在您的主窗口中假设以下内容

<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,不需要动态视图代码。只需使用您的视图模型即可。

ps:随时编辑我的糟糕英语。

于 2012-07-06T07:40:32.783 回答