WPF绑定到Listbox selectedItem

Oli*_*lis 30 wpf binding listbox selecteditem

任何人都可以帮助以下 - 一直在玩这个,但不能为我的生活让它工作.

我有一个包含以下属性的视图模型;

public ObservableCollection<Rule> Rules { get; set; }
public Rule SelectedRule { get; set; }
Run Code Online (Sandbox Code Playgroud)

在我的XAML中,我得到了;

<ListBox x:Name="lbRules" ItemsSource="{Binding Path=Rules}" 
         SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}">
<ListBox.ItemTemplate>
    <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name:" />
                <TextBox x:Name="ruleName">
                    <TextBox.Text>
                        <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" />
                    </TextBox.Text>
                </TextBox>
            </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)

现在ItemsSource工作正常,我得到一个Rule对象列表,其名称显示在lbRules中.

我遇到的麻烦是将SelectedRule属性绑定到lbRules的SelectedItem.我尝试将textblock的text属性绑定到SelectedRule,但它始终为null.

<TextBlock Text="{Binding Path=SelectedRule.Name}" />
Run Code Online (Sandbox Code Playgroud)

我在输出窗口中看到的错误是:BindingExpression路径错误:找不到'SelectedRule'属性.

任何人都可以帮助我这个绑定 - 我不明白为什么它不应该找到SelectedRule属性.

然后我尝试将textblock的text属性更改为bellow,这有效.麻烦的是我想在我的ViewModel中使用SelectedRule.

<TextBlock Text="{Binding ElementName=lbRules, Path=SelectedItem.Name}" />
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助.

arc*_*aut 25

首先,您需要INotifyPropertyChanged在视图模型中实现接口,并PropertyChangedRule属性的setter中引发事件.否则,没有任何绑定到该SelectedRule属性的控件将"知道"它何时被更改.

然后,你的XAML

<TextBlock Text="{Binding Path=SelectedRule.Name}" />
Run Code Online (Sandbox Code Playgroud)

如果它TextBlockListBoxs 之外ItemTemplate并且与之相同DataContext,那么它是完全有效的ListBox.


Max*_*kin 11

DataTemplate你的内部工作Rule,这就是你无法绑定的原因SelectedRule.Name- 没有这样的属性Rule.要绑定到原始数​​据上下文(这是您的ViewModel),您可以编写:

<TextBlock Text="{Binding ElementName=lbRules, Path=DataContext.SelectedRule.Name}" />
Run Code Online (Sandbox Code Playgroud)

更新:关于SelectedItem属性绑定,它看起来完全有效,我在我的机器上尝试相同,它工作正常.这是我的完整测试应用程序:

XAML:

<Window x:Class="TestWpfApplication.ListBoxSelectedItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ListBoxSelectedItem" Height="300" Width="300"
    xmlns:app="clr-namespace:TestWpfApplication">
    <Window.DataContext>
        <app:ListBoxSelectedItemViewModel/>
    </Window.DataContext>
    <ListBox ItemsSource="{Binding Path=Rules}" SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Name:" />
                    <TextBox Text="{Binding Name}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>
Run Code Online (Sandbox Code Playgroud)

代码背后:

namespace TestWpfApplication
{
    /// <summary>
    /// Interaction logic for ListBoxSelectedItem.xaml
    /// </summary>
    public partial class ListBoxSelectedItem : Window
    {
        public ListBoxSelectedItem()
        {
            InitializeComponent();
        }
    }


    public class Rule
    {
        public string Name { get; set; }
    }

    public class ListBoxSelectedItemViewModel
    {
        public ListBoxSelectedItemViewModel()
        {
            Rules = new ObservableCollection<Rule>()
            {
                new Rule() { Name = "Rule 1"},
                new Rule() { Name = "Rule 2"},
                new Rule() { Name = "Rule 3"},
            };
        }

        public ObservableCollection<Rule> Rules { get; private set; }

        private Rule selectedRule;
        public Rule SelectedRule
        {
            get { return selectedRule; }
            set
            {
                selectedRule = value;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)