2013-11-27 50 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')