2016-06-10 60 views
0

我知道这有很多问题,但我找不到正确的答案,或者我不明白正确的解决方法。 我有我的列表框在主窗口,它是由自定义对象(FooObjClass)填充。如何使用MVVM管理列表框中的用户控件?

<ListBox x:Name="FooListBox"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <fooNameSpace:FooObjView/>      
      </DataTemplate> 
     </ListBox.ItemTemplate> 
</ListBox> 

的FooObjView是用户控制

<UserControl x:Class="PLCS7_TEST.SmartObjRecognize.SmartObjView" 
     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" 
     xmlns:local="clr-namespace:Test.FooObjRecognize" 
     mc:Ignorable="d" Width="Auto"> 
<UserControl.DataContext> 
    <local:FooViewModel/> 
</UserControl.DataContext> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto"/> 
     <ColumnDefinition Width="Auto"/> 
    </Grid.ColumnDefinitions> 
    <TextBlock Grid.Column="0" Text="{Binding Path=FooObjprop.Name}"/> 
    <TextBlock Grid.Column="1" Text="{Binding Path=FooObjprop.Type}"> 
</Grid> 

,这是我FooViewModel

class FooViewModel : ObservableObject 
{ 
    private FooObjClass fooObjmember; 

    public FooObjClass FooObjprop 
    { 
     get { return fooObjmember; } 
     set 
     { 
      this.fooObjmember= value; 
      base.RaisePropertyChanged("FooObjprop"); 
     } 
    } 
} 

的FooObjClass是正常类和ObservableObject类是这样的:

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

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     var handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 

    protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion) 
    { 
     var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion); 
     this.RaisePropertyChanged(propertyName); 
    } 

    protected void RaisePropertyChanged(String propertyName) 
    { 
     VerifyPropertyName(propertyName); 
     OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
    } 

    public void VerifyPropertyName(String propertyName) 
    { 
     // verify that the property name matches a real, 
     // public, instance property on this Object. 
     if (TypeDescriptor.GetProperties(this)[propertyName] == null) 
     { 
      Debug.Fail("Invalid property name: " + propertyName); 
     } 
    } 
} 

现在,我可以做什么将列表框(它是FooObjClass)的项目对象传递给最后一个FooModelView?我必须使用依赖属性?但是如何?我tryed我readed,但是我没有找到解决办法

着这片代码,我可能到列表框中的项目对象传递给FooViewModel

<UserControl.DataContext> 
    <local:FooViewModel fooObjmember="{Databinding}"/> 
</UserControl.DataContext> 

但fooObjmember不是依赖属性,当我试图创建一个依赖属性它是相同的

谢谢你,我的英语水平很抱歉;)

回答

0

欢迎,

这里是你的错误:

  • 你不指定一个ListBoxItem的
  • 您实例在用户控件
  • 要绑定到现场fooObjmember另一种模式的结合,只有特性允许

这里有一个工作示例:

窗口XAML

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <!--<ListBox ItemsSource="{Binding}"> binds to DataContext property--> 
     <ListBox ItemsSource="{Binding}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <local:MyUserControl DataContext="{Binding}" /> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 
</Window> 

窗口代码

using System.Collections.Generic; 

namespace WpfApplication1 
{ 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      DataContext = new List<MyModel> 
      { 
       new MyModel {Number = 1, Value = "one"}, 
       new MyModel {Number = 2, Value = "two"} 
      }; 
     } 
    } 
} 

用户控制XAML

<UserControl x:Class="WpfApplication1.MyUserControl" 
      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" 
      xmlns:local="clr-namespace:WpfApplication1" 
      mc:Ignorable="d" d:DataContext="{d:DesignInstance local:MyModel}" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <Border Padding="5" BorderBrush="Red" BorderThickness="1"> 
      <StackPanel> 
       <TextBlock Text="{Binding Number}" /> 
       <TextBlock Text="{Binding Value}" /> 
      </StackPanel> 
     </Border> 
    </Grid> 
</UserControl> 

用户控制代码

namespace WpfApplication1 
{ 
    public partial class MyUserControl 
    { 
     public MyUserControl() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

型号代码

using System.ComponentModel; 
using System.Runtime.CompilerServices; 

namespace WpfApplication1 
{ 
    internal class MyModel : INotifyPropertyChanged 
    { 
     private int _number; 
     private string _value; 

     public int Number 
     { 
      get { return _number; } 
      set 
      { 
       if (value == _number) return; 
       _number = value; 
       OnPropertyChanged(); 
      } 
     } 

     public string Value 
     { 
      get { return _value; } 
      set 
      { 
       if (value == _value) return; 
       _value = value; 
       OnPropertyChanged(); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

结果

enter image description here

现在调整,为您的需求:d

+0

感谢@Aybe,我给自己定德listbox.Datacontext因为我有其他人认为窗口,我从你的代码复制其余的,这一切没有任何限制,但用户控件中的datacontext为null。列表框里面有项目。 – ek32

+0

你应该发布一些代码... – Aybe

+0

它是一样的,你发布,唯一的区别是在窗口代码。而不是DataContext =新列表我写了listbox.Datacontext =新列表。当我调试我看到列表框中的对象,但在用户控件插入var x = this.Datacontext(在InitializeComponent()后)我看到它是空的。 – ek32

相关问题