2013-04-18 80 views
0

我正在開發一個execise應用程序。我的應用程序採用MVVM。我正在嘗試創建一個包含兩個用戶控件的窗口,其中一個用戶控件包含一個從viewmodel獲取其數據的datagrid。
我希望datagrid在應用運行時自動填充我的默認值(私有文件)。但是存在綁定錯誤: System.Windows.Data錯誤:4:找不到與參考'ElementName = windowView'綁定的源。 BindingExpression:路徑= ActivePacket;的DataItem = NULL;目標元素是'DataGrid'(Name ='dataGrid1');目標屬性是'ItemsSource'(類型'IEnumerable')UserControl中的數據綁定問題

謝謝!

這裏是我的代碼:

========= MainWindow.xaml ================

<Window x:Class="Project.Abc.Try.MainWindow" 
     x:Name="windowView" 
     xmlns:local="clr-namespace:Project.Abc.Try" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="600"> 

    <Window.DataContext> 
     <local:PayloadViewModel /> 
    </Window.DataContext> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="78*" /> 
      <RowDefinition Height="233*" /> 
     </Grid.RowDefinitions> 

     <local:CmdMenuView Grid.Row="0" Margin="6,6,3,6" /> 
     <local:PayloadView Grid.Row="1" Margin="6,6,3,6" /> 
    </Grid> 
</Window> 

== ========== PayloadView.xaml ===========

<UserControl x:Class="Project.Abc.Try.PayloadView" 
      x:Name="PLview" 
      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="199" d:DesignWidth="588" > 

    <Grid Height="200" Width="580" > 
     <!--<DataGrid AutoGenerateColumns="False" Height="45" HorizontalAlignment="Left" Margin="36,20,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="500" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=ActivePacket}"> --> 
     <DataGrid AutoGenerateColumns="False" Height="45" HorizontalAlignment="Left" Margin="36,20,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="500" ItemsSource="{Binding ElementName=windowView, Path=ActivePacket}"> 

       <DataGrid.Columns> 
       <DataGridTextColumn Binding="{Binding PacketId, Mode=TwoWay}" Header="PacketID " Width="*" /> 
       <DataGridTextColumn Binding="{Binding PacketLength, Mode=TwoWay}" Header="PacketLength" Width="*" /> 
       <DataGridTextColumn Binding="{Binding Spare}" Header="Byte 6" Width="*" /> 
      </DataGrid.Columns> 
     </DataGrid> 
     <Button Content="Send" Command="{Binding Path=SendCommand}" Height="23" HorizontalAlignment="Left" Margin="310,122,0,0" Name="button1" VerticalAlignment="Top" Width="75" /> 
    </Grid> 
</UserControl> 

=================== PayloadViewModel.cs ========================

namespace Project.Abc.Try 
{ 
    public class PayloadViewModel : ObservableObject 
    { 
     // ...... 
     private CmdPacket _activePacket; 
     public CmdPacket ActivePacket 
     { 
      get { return _activePacket; } 
      set 
      { 
       if (value != _activePacket) 
       { 
        _activePacket = value; 
        OnPropertyChanged("ActivePacket"); 
       } 
      } 
     } 
     // ......... 
} 

回答

3

您必須將DataContext分配給您的視圖MainWindow.xaml

<local:PayloadView ... DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}" /> 

而在PayloadView.xaml,只要綁定到視圖模型屬性:

<DataGrid ... ItemsSource="{Binding ActivePacket}" /> 
+0

謝謝,我根據你的建議修改了我的代碼。綁定錯誤消息已經消失,但我仍然看不到任何數據顯示在UI上的DataGrid中。調試 - 輸出窗口總是有「System.Windows.Data信息:10:不能使用綁定檢索值,並且不存在有效的回退值;使用默認值而不是BindingExpression:Path = ActivePacket; DataItem = null;目標元素是'DataGrid'( Name ='dataGrid1');目標屬性是'ItemsSource'(類型'IEnumerable') 「。有什麼問題? –

+0

@KaiMon CmdPacket是集合類型嗎?是否初始化?請在http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource.aspx上閱讀有關'DataGrid.ItemsSource'的更多信息,以幫助您解決這個問題。 –

+0

謝謝。我發現程序沒有創建CmdPacket對象,因爲它的構造器沒有正確設置。 –

0

一些想法... 如果你不」除PayloadView以外的任何地方都需要PayloadViewModel,您可以直接在您的PayloadView的DataContext中綁定PayloadViewModel,然後直接綁定它。另外,如果你想要做MVVM,你可能要考慮使用Caliburn.Micro,如果你還沒有。如果你不想做MVVM,你可能會考慮使用Caliburn.Micro。它會自動將每個View的datacontext綁定到相應的ViewModel,而無需代碼(即PayloadView將自動訪問PayloadViewModel上的公共屬性)。然後你會寫是:

<UserControl x:Class="Project.Abc.Try.PayloadView" ...> 

    ... 

    <DataGrid ... ItemsSource="{Binding ActivePacket}" /> 

    ... 

</UserControl> 

這裏是Caliburn.Micro一個偉大的教程:http://www.mindscapehq.com/blog/index.php/2012/01/12/caliburn-micro-part-1-getting-started/

希望這有助於。

+0

謝謝,這聽起來很有吸引力。將研究它! –