2013-05-07 6 views
0

У меня 2 пользовательских элементов управления в MainWindow.xaml, они SidePannel и Description. Я передаю объект DictionaryModel. В объекте DictionaryModel есть коллекция Words и еще один объект под названием SidePannelModel. В SidePannelModel имеется еще одна коллекция Words и свойство string.WPF Data Binding-Binding Obj. внутри Obj. to UserControl

DictionaryModel 

public class DictionaryModel : INotifyPropertyChanged 
{ 

    public event PropertyChangedEventHandler PropertyChanged; 

    public SidePannelModel SideModel { get; set; } 
    public IEnumerable<WordModel> Language2 { get; set; } 

    public void ToggleLanguage() 
    { 
     var temp = this.Language2; 
     this.Language2 = this.SideModel.Language1; 
     this.SideModel.Language1 = temp; 

     OnPropertyChanged("DictionaryChanged"); 
    } 


    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

SidePannelModel 

public class SidePannelModel 
{ 
    public IEnumerable<WordModel> Language1 { get; set; } 
    public string SearchWord { get; set; } 
} 

Я передаю DictionaryModel к DataContext в MainWindow.xaml.cs.

public partial class MainWindow : Window 
    { 
     private DictionaryModel dictionary; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      dictionary = new DictionaryModel 
      { 
        SideModel = new SidePannelModel { 
        SearchWord=null, 
        Language1 = new List<WordModel>() 
        { 
         new WordModel() { Word = "Test1" } 
         , new WordModel() { Word = "Test2" } 
         , new WordModel() { Word = "Test3" } 
         , new WordModel() { Word = "Test4" } 
         , new WordModel() { Word = "Test5" } 
         , new WordModel() { Word = "Test6" } 
         , new WordModel() { Word = "Test7" } 
         , new WordModel() { Word = "Test8" } 
         , new WordModel() { Word = "Test9" } 
         , new WordModel() { Word = "Test10" } 

        } as IEnumerable<WordModel> 
       }, 


       Language2 = new List<WordModel>() 
       { 
        new WordModel() { Word = "Test1" } 
        , new WordModel() { Word = "Test2" } 
        , new WordModel() { Word = "Test3" } 
        , new WordModel() { Word = "Test4" } 
        , new WordModel() { Word = "Test5" } 
        , new WordModel() { Word = "kkkkk" } 
        , new WordModel() { Word = "Test7" } 
        , new WordModel() { Word = "Test8" } 
        , new WordModel() { Word = "Test9" } 
        , new WordModel() { Word = "Test10" } 

       } as IEnumerable<WordModel>, 

      }; 

      this.DataContext = dictionary; 
     } 
    } 

Это, как я прохожу Коллекция Words и SidePannelModel к контроллерам пользователя в ManiWindow.xaml

<Window x:Class="ThaiDictionary.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sidePanel="clr-namespace:ThaiDictionary" 
    Title="MainWindow" 
    Height="619"> 
<Window.Resources> 
    <Style TargetType="{x:Type ToggleButton}" 
     x:Key="toggleButtonStyle"> 
     <Style.Triggers> 
      <Trigger Property="IsChecked" Value="True"> 
       <Setter Property="Content" Value="Thai to English" /> 
      </Trigger> 
      <Trigger Property="IsChecked" Value="False"> 
       <Setter Property="Content" Value="English to Thai" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 

<Grid Margin="0,0,2,0"> 

    <DockPanel LastChildFill="True"> 
     <Menu IsMainMenu="True" DockPanel.Dock="Top"> 
      <MenuItem Header="_File" /> 
      <MenuItem Header="_Edit" /> 
      <MenuItem Header="_View" /> 
      <MenuItem Header="_Window" /> 
      <MenuItem Header="_Help" /> 
     </Menu> 
     <StatusBar Height="22" DockPanel.Dock="Bottom"/> 
     <sidePanel:SidePanel SideModel="{Binding SidePModel, Mode=TwoWay}" DockPanel.Dock="Left" MinWidth="200" MinHeight="540" Margin="5,5,5,1" Width="196"/> 
     <DockPanel LastChildFill="True" DockPanel.Dock="Left"> 
      <ToggleButton IsChecked="False" DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Width="150" Style="{StaticResource toggleButtonStyle}" Checked="ToggleButton_Checked" Unchecked="ToggleButton_Unchecked"> 
      </ToggleButton> 
      <sidePanel:Description DockPanel.Dock="Top" WordsList2="{Binding Language2, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
     </DockPanel> 

    </DockPanel> 

</Grid> 

SideModel определяется в SidePannel.xaml.cs.

public partial class SidePanel : UserControl 
{ 
    public static DependencyProperty SideModelProperty; 


    static SidePanel() 
    { 
     SideModelProperty = DependencyProperty.Register("SideModel", typeof(SidePannelModel), typeof(SidePanel)); 
    } 

    public SidePanel() 
    { 
     InitializeComponent(); 

    } 


    public SidePannelModel SideModel 
    { 
     get 
     { 
      return (SidePannelModel)GetValue(SideModelProperty); 
     } 
     set 
     { 
      SetValue(SideModelProperty, value); 
     } 
    } 

} 

Но контроллер SidePanel не загружается с Word с я ожидал.

соответствующая часть SidePanel.xaml приведена ниже.

<UserControl x:Class="ThaiDictionary.SidePanel" 
     x:Name="SidePannelController" 
     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:l="clr-namespace:ThaiDictionary" 
     mc:Ignorable="d" MinHeight="300" MinWidth="300" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Azure"> 
<UserControl.Resources> 

</UserControl.Resources> 

<DockPanel LastChildFill="True" DataContext="{Binding SidePModel}"> 
    <l:SearchTextBox SearchEventTimeDelay="00:00:02.00" Text="{Binding ElementName= SidePannelController, Path= SearchWord, Mode=TwoWay}" DockPanel.Dock="Top" Search="SearchTextBox_Search" HorizontalAlignment="Stretch" Background="Bisque"/> 
    <ListBox Name="LeftSidePnel1" ItemsSource="{Binding ElementName= SidePannelController, Path= Language1, Mode=TwoWay}" HorizontalAlignment="Stretch" 
     VerticalAlignment="Stretch" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" ItemTemplate="{DynamicResource WordTemplate}" MinHeight="266" Height="auto" > 
     <ListBox.Resources> 
      <DataTemplate x:Key="WordTemplate"> 
       <Label Content="{Binding Word}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="auto"/> 
      </DataTemplate> 
     </ListBox.Resources> 
    </ListBox> 
</DockPanel> 

Но когда я запускаю проект, я не могу видеть слова, загруженные в UserControl к Sidepanel. Что не так с этим кодом. Я не могу найти выход. Не могли бы вы мне немного помочь.

Edit:

Я следовал соглашения об именах и изменил SidePannel.xaml.cs.

Binding ошибка:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=SidePanelController'. BindingExpression:Path=SearchWord; DataItem=null; target element is 'SearchTextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=SidePanelController'. BindingExpression:Path=Language1; DataItem=null; target element is 'ListBox' (Name='LeftSidePnel1'); target property is 'ItemsSource' (type 'IEnumerable') 

Я добавил полный SidePanel.xaml и я изменил ELEMENTNAME к SidePannelController, как в файле XAML. Но до сих пор не получают загружающего слова

правка:

System.Windows.Data Information: 41 : BindingExpression path error: 'SearchWord' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=SideModel.SearchWord; DataItem='SidePanel' (Name='SidePannelController'); target element is 'SearchTextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=SideModel.SearchWord; DataItem='SidePanel' (Name='SidePannelController'); target element is 'SearchTextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=SideModel.SearchWord; DataItem='SidePanel' (Name='SidePannelController'); target element is 'SearchTextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=SideModel.SearchWord; DataItem='SidePanel' (Name='SidePannelController'); target element is 'SearchTextBox' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Information: 41 : BindingExpression path error: 'Language1' property not found for 'object' because data item is null. This could happen because the data provider has not produced any data yet. BindingExpression:Path=SideModel.Language1; DataItem='SidePanel' (Name='SidePannelController'); target element is 'ListBox' (Name='LeftSidePnel1'); target property is 'ItemsSource' (type 'IEnumerable') 
System.Windows.Data Information: 20 : BindingExpression cannot retrieve value due to missing information. BindingExpression:Path=SideModel.Language1; DataItem='SidePanel' (Name='SidePannelController'); target element is 'ListBox' (Name='LeftSidePnel1'); target property is 'ItemsSource' (type 'IEnumerable') 
System.Windows.Data Information: 21 : BindingExpression cannot retrieve value from null data item. This could happen when binding is detached or when binding to a Nullable type that has no value. BindingExpression:Path=SideModel.Language1; DataItem='SidePanel' (Name='SidePannelController'); target element is 'ListBox' (Name='LeftSidePnel1'); target property is 'ItemsSource' (type 'IEnumerable') 

Благодаря

+0

Может быть, все, что вам нужно сделать, это исправление вашей DependencyProperty декларации из Dependency Название недвижимости конвенций. См. Мой ответ [здесь] (http://stackoverflow.com/a/16404640/620360). – LPL

+0

@LPL Я правильно соблюдал правила именования, но проблема такая же. –

+0

Получаете ли вы какие-либо ошибки привязки в окне 'Output'? Кроме того, вы привязываетесь к элементу с именем 'SidePannelController2' - можете ли вы показать полный XAML для того, где этот элемент управления и где' SidePanel' 'UserControl' ссылается на него? Я подозреваю, что ваша проблема может заключаться в том, что привязка не может найти элемент с именем 'SidePannelController2' в дополнение к VisualTree из вашего' SidePanel' – Rachel

ответ

1

Language1 и SearchWord не являются собственностью вашего UserControl, они являются собственностью вашего UserControl.SideModel.

Меняют привязки включить SideModel в вашем Path собственности, так что это правильно связывается с SidePannelController.SideModel.Language1 (или SearchWord), как это:

ItemsSource="{Binding ElementName=SidePannelController, Path=SideModel.Language1}" 

Но я подозреваю, что вы не показываете фактическую XAML, потому что ваша ошибка связи говорит «Не удается найти источник для привязки», что означает, что он не может найти элемент с именем SidePannelController в VisualTree (так как ElementName указывает источник, который будет использоваться для привязки).

Если это так, то вы можете попробовать с помощью RelativeSource связывания, чтобы найти UserControl вместо ElementName

ItemsSource="{Binding Path=SideModel.Language1, 
    RelativeSource={RelativeSource AncestorType={x:Type l:SidePanel}}" 
+0

Большое вам спасибо. Проблема решена. Еще одна вещь. Несмотря на то, что слова загружаются в боковую панель, окно «Выход» все еще показывает ошибку привязки. как показано в новом Edit.Do вы знаете, что вызывает эту проблему? –

+0

@Diode Вы получаете ошибку привязки в любое время, когда привязка пытается оценить значение и не удается. Есть много причин, по которым это может быть неудачно, однако наиболее распространенным является то, что «DataContext» (элемент данных) неверен. Недавно я написал ответ «SO» о [отладке ошибок привязки WPF] (http://stackoverflow.com/a/14523290/302677), которые могут оказаться полезными. Подводя итог, разбейте свою ошибку двоеточиями/точкой с запятой и прочитайте ее назад, чтобы понять точное местоположение ошибки и проблемы. – Rachel

+0

Ничего себе, спасибо за очень конструктивный и подробный и выделенный ответ. Цените много (Up Vote + Correct Answer + Up vote для соответствующего ответа), Надеюсь, вы дадите некоторую помощь и в WPF в будущем. :) –

-1

Я не знаю, что DictionaryModel есть.

Может быть опечатка, но возможно у вас есть в MainWindow.xaml.cs дополнительный }, прямо перед:

Language2 = new List<WordModel>()

Это означало бы, что Language2 не является членом dictionary.SideModel, но вместо того, чтобы еще один , отдельный элемент коллекции (свойство sibling SideModel?)

Однако в MainWindow.xaml, вы привязываетесь к языку2 внутри привязки к SideModel. Поскольку Language2 не является дочерним элементом SideModel, XAML не может разрешить привязку.

+0

Нет, это не опечатка, я добавил DictionaryModel. :) –

Смежные вопросы