Привязка данных не работает в словаре ресурсов - PullRequest
0 голосов
/ 18 февраля 2011

Я пытаюсь привязать свойство SelectedItem списка к двум элементам управления текстовым полем.Эти элементы управления расположены в разделе ресурсов Windows.Идея состоит в том, что когда запись в списке выбирается, два элемента управления textbox отображают «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 TextBox остаются пустыми, когдаЯ нажимаю на кнопку.Окно списка заполняется нормально.Я подтвердил, что могу получить свойства BlockToolBar и создать его в списке.

Окно вывода Visual Studio (экспресс) дает мне следующее: System.Windows.Data Ошибка: 4: Не удается найти источникдля привязки со ссылкой 'ElementName = lsbCommonBlocks'.BindingExpression: Path = SelectedItem;DataItem = NULL;целевым элементом является 'StackPanel' (Name = '');Свойство target - «DataContext» (тип «Object»)

Не уверен, что я делаю неправильно.Я немного новичок в WPF.

Если я удалю ресурс стековой панели (testsp) и заменим contentcontrol на элементы управления testp, тогда привязки данных будут работать.Я также могу связать txt1 и txt2 непосредственно с объектом BlockToolBar в ресурсе, но я не могу связать txt1 / txt2 с выбранным элементом, если в ресурсе.

Причина, по которой я это делаю, заключается в том, что у меня естьсложное главное окно, которое я разбиваю на отдельные ресурсные словари и вызываю свое главное окно с помощью контент-контроля.Когда я не мог заставить это работать, я создаю более простой проект, чтобы попытаться сузить мою проблему.

1 Ответ

0 голосов
/ 18 февраля 2011

Похоже, нужно создать привязку в коде.Я сделал следующие изменения, и это сработало.Думаю, я пробовал это раньше, но ...

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;

    }
...