2011-02-18 4 views
0

リストボックスのSelectedItemプロパティを2つのテキストボックスコントロールにバインドしようとしています。これらのコントロールは、Windowsリソースセクションにあります。考え方は、リストボックス内の項目が選択されたときに、2つのテキストボックスコントロールが私のカスタムクラスから "blockName"と "blockHelpText"を表示するというものです。 but1ボタンをクリックしてリストボックスをロードします。データバインディングがリソース辞書内で動作しない

<Window.Resources> 
<StackPanel x:Key="testsp" Visibility="Visible" DataContext="{Binding ElementName=lsbCommonBlocks, Path=SelectedItem, diagnostics:PresentationTraceSources.TraceLevel=High}"> 
     <ListBox x:Name="lsbCommonBlocks" DisplayMemberPath="BlockName" SelectionChanged="lb_sc"/> 
     <Button x:Name="but1" Click="but1_click" Content="Button 1"/> 
     <TextBox x:Name="txt1" Text="{Binding Path=BlockName, diagnostics:PresentationTraceSources.TraceLevel=High}"/> 
     <TextBox x:Name="txt2" Text="{Binding Path=BlockHelpText, diagnostics:PresentationTraceSources.TraceLevel=High}"/> 
    </StackPanel> 
</Window.Resources> 
<Grid> 
    <ContentControl Visibility="Visible" x:Name="contentWorkArea" Content="{StaticResource testsp}"/> 
</Grid> 

クリックイベントは、リストボックスのItemsourcesプロパティをカスタムクラスBlockToolBarに関連付けます。

BlockToolBar[] blocks = { new BlockToolBar("Block 1", "No help for this block."), 
           new BlockToolBar("Block 2", "Help."), 
           new BlockToolBar("Block 3", "Help again.") }; 

private void but1_click(object sender, RoutedEventArgs e) 
    { 
     StackPanel sp = (StackPanel)this.TryFindResource("testsp"); 
     ListBox lb = (ListBox)LogicalTreeHelper.FindLogicalNode(sp, "lsbCommonBlocks"); 
     lb.ItemsSource = blocks; 
    } 

public class BlockToolBar : INotifyPropertyChanged 
{ 
    private string blockName; 
    public string BlockName 
    { 
     get { return blockName; } 
     set { 
      blockName = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("BlockName")); 
     } 
    } 

    private string blockHelpText; 
    public string BlockHelpText 
    { 
     get { return blockHelpText; } 
     set { 
      blockHelpText = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("BlockHelpText")); 
     } 
    } 

    public BlockToolBar() 
    { 
     blockName = ""; 
     blockHelpText = ""; 
    } 

    public BlockToolBar(string BlockName, string BlockHelpText) 
    { 
     blockName = BlockName; 
     blockHelpText = BlockHelpText; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, e); 
    } 
} 

データバインディングが機能しません:テキストボックスのtxt1とtxt2は、ボタンをクリックすると空白のままです。リストボックスにはOKが入力されます。私は、リストボックスにイベントを作成することで、BlockToolBarプロパティを取得できることを確認しました。

Visual Studio(express)出力ウィンドウが表示されます。System.Windows.Dataエラー:4: 'ElementName = lsbCommonBlocks'という参照でバインド元が見つかりません。 BindingExpression:Path = SelectedItem; DataItem = null;ターゲット要素は 'StackPanel'(Name = '');対象のプロパティが 'DataContext'(タイプ 'Object')

私が間違っていることを確認できません。 WPFの新機能です。

stackpanelリソース(testsp)を削除し、contentcontrolをtestspコントロールに置き換えると、データバインディングが機能します。また、リソース内のBlockToolBarオブジェクトに直接txt1とtxt2をバインドすることもできますが、リソース内にある場合はtxt1/txt2をselecteditemにバインドすることはできません。

私はこれをやっている理由は、別の独立したリソースに分割され、contentcontrols経由で私のメインウィンドウに呼び出す複雑なメインウィンドウがあるということです。私がそれを働かせることができないとき、私は問題を絞り込むためのより簡単なプロジェクトを作成します。

答えて

0

コード内にバインディングを作成する必要があります。私は以下の変更を加え、それがうまくいった。私はこれを前に試したと思ったけど...

private void but1_click(object sender, RoutedEventArgs e) 
    { 
     StackPanel sp = (StackPanel)this.TryFindResource("testsp"); 
     ListBox lb = (ListBox)LogicalTreeHelper.FindLogicalNode(sp, "lsbCommonBlocks"); 

     Binding myBinding = new Binding(); 
     myBinding.Source = lb; 
     myBinding.Path = new PropertyPath("SelectedItem"); 
     sp.SetBinding(StackPanel.DataContextProperty, myBinding); 

     lb.ItemsSource = blocks; 

    } 
関連する問題