2013-11-27 52 views
1

因此,如前面提到的问题中,我问WPF Data Binding From UserControl我有成功的基础绑定了我的控件的TabHeader基于我的UserControls代码中的值使用DependencyProperty后面的文件,并实现了一个类似用INotifyPropertyChanged实现。WPF从UserControl视图模型绑定主窗口控件

但是我现在需要它来处理UserControls ViewModel的值。我可以使用INotifyPropertyChanged成功更新UserControl UI,但我无法将此值绑定到主窗口中的TabItem控件,因为它似乎将其重新生成。

这是甚至可能还是我吠错了树?

主窗口(的TabControl)< --->用户控件< --->视图模型

MainWindow.xaml

<Grid> 
     <TabControl Height="250" HorizontalAlignment="Left" Margin="12,26,0,0" Name="tabControl1" VerticalAlignment="Top" Width="479"> 
      <TabControl.Resources> 
       <Style TargetType="TabItem" x:Key="tab1ItemHeaderStyle" > 
        <Setter Property="HeaderTemplate" > 
         <Setter.Value> 
          <DataTemplate DataType="{x:Type TabItem}"> 
           <StackPanel Orientation="Horizontal"> 
            <Label Content="{Binding Path=Header, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}"/> 
            <Label Content="{Binding Path=SomeFigureVM, ElementName=uc1}"/> 
           </StackPanel> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </TabControl.Resources> 
      <TabItem Style="{StaticResource tab1ItemHeaderStyle}" Header="[Tab 1]" Name="tabItem1"> 
       <vw:UserControl1 x:Name="uc1"></vw:UserControl1> 
      </TabItem> 
     </TabControl> 
    </Grid> 

UserControl1.xaml

<Grid> 
    <Label Height="43" HorizontalAlignment="Left" Margin="69,128,0,0" Name="textBlock" Content="{Binding SomeFigureVM}" VerticalAlignment="Top" Width="100" /> 
    <Button Name="updateSomeFigure" Content="Update.." Click="updateSomeFigure_Click" Width="100" Height="100" Margin="69,12,66,71" /> 
</Grid> 

UserControl1.xaml.cs

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
     this.DataContext = new MyViewModel(); 
    } 

    private void updateSomeFigure_Click(object sender, RoutedEventArgs e) 
    { 
     MyViewModel viewmodel = this.DataContext as MyViewModel; 

     viewmodel.UpdateFigure(); 
    } 
} 

MyViewModel.cs

public class MyViewModel: INotifyPropertyChanged 
    { 
     public MyViewModel() 
     { 
      this.SomeFigureVM = 23; 
     } 

     private int _someFigure; 


     public int SomeFigureVM 
     { 
      get 
      { 
       return _someFigure ; 
      } 
      set 
      { 
       _someFigure = value; 
       NotifyPropertyChanged("SomeFigureVM"); 
      } 
     } 

     public void UpdateFigure() 
     { 
      SomeFigureVM = SomeFigureVM + 1; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(string property) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(property)); 
      } 
     } 
    } 

与往常一样,任何帮助是极大的赞赏,我觉得我已经砸我的头撞墙就这一个!

+0

[不要将DataContext硬编码到UserControl中](http://stackoverflow.com/a/16488618/302677)。它击败了WPF拥有独立UI和数据层的最大好处之一。如果你有兴趣,我有一篇博客文章可以帮助你更好地理解WPF的'DataContext':[你说的这个“DataContext”是什么?](http://rachel53461.wordpress.com/2012/07/14/what-this-this-datacontext-you-speak-of /) – Rachel

+0

谢谢你的链接!真的很好的建议! – metoyou

回答

2

SomeFigureVM是您的MyViewModel的一个属性,它是UserControl1DataContext。您正尝试访问UserControl上的SomeFigureVM属性,该属性不存在。

改变这一行:

<Label Content="{Binding Path=SomeFigureVM, ElementName=uc1}"/> 

<Label Content="{Binding Path=DataContext.SomeFigureVM, ElementName=uc1}"/> 

为了赶上数据绑定这样的错误,在调试模式下的应用程序并观察任何数据绑定问题的输出窗口。您的原始代码生成数据绑定错误,如:

System.Windows.Data Error: 40 : BindingExpression path error: 'SomeFigureVM' property not found on 'object' ''UserControl1' (Name='uc1')'. BindingExpression:Path=SomeFigureVM; DataItem='UserControl1' (Name='uc1'); target element is 'Label' (Name=''); target property is 'Content' (type 'Object')