c# - WPF 文本框绑定问题 DataItem = null?
问题描述
我是 WPF 框架的新手。文本框的属性“文本”的数据绑定不起作用。不知道代码有没有问题?
我有一个名为“ConfigListBox”的列表框和一个名为“NameTextBox”的文本框。
<ListBox x:Name="ConfigListBox" Grid.Row="0" Loaded="ConfigListBox_OnLoaded">
<ListBox.ItemTemplate>
<DataTemplate DataType="MyApp:Config">
<WrapPanel>
<CheckBox Margin="0, 0, 2, 0"/>
<TextBlock Text="{Binding Name}" />
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Name="NameTextBox" Grid.Column="1" Grid.Row="0" Text="{Binding SelectedConfig.Name}"></TextBox>
Object _selectedConfig 是 ConfigListBox 的选中项的实例。_selectedConfig 将在 ConfigListBox 处于选定索引更改事件时更新。
public partial class MainWindow : Window, INotifyPropertyChanged
{
private List<Config> _configs = new List<Config>();
private Config _selectedConfig;
public Config SelectedConfig
{
get => _selectedConfig;
set
{
_selectedConfig = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Config 类实现了 INotifyPropertyChanged 接口。
class Config : INotifyPropertyChanged
{
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
找到数据上下文元素:?DataItem=null?,详细日志:
System.Windows.Data Warning: 67 : BindingExpression (hash=55056607): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=55056607): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 : Lookup name _selectedConfig: queried TextBox (hash=14620943)
System.Windows.Data Warning: 67 : BindingExpression (hash=55056607): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=55056607): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 : Lookup name _selectedConfig: queried TextBox (hash=14620943)
System.Windows.Data Warning: 67 : BindingExpression (hash=55056607): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=55056607): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 : Lookup name _selectedConfig: queried TextBox (hash=14620943)
System.Windows.Data Warning: 67 : BindingExpression (hash=55056607): Resolving source (last chance)
System.Windows.Data Warning: 70 : BindingExpression (hash=55056607): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 : Lookup name _selectedConfig: queried TextBox (hash=14620943)
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=_selectedConfig'. BindingExpression:Path=Name; DataItem=null; target element is 'TextBox' (Name='NameTextBox'); target property is 'Text' (type 'String')
解决方案
您的示例中没有命名元素。_selectedConfig
确实有一个具有该名称的字段,但您不能绑定到字段,只能绑定到公共属性。
所以你应该_selectedConfig
变成一个属性,把它的名字改成S selectedConfig。
您还需要INotifyPropertyChanged
在您打算动态设置其属性的对象上实现,即MainWindow
在这种情况下:试试这个:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private Config _selectedConfig;
public Config SelectedConfig
{
get { return _selectedConfig; }
set { _selectedConfig = value; OnPropertyChanged(); }
}
private void ConfigListBox_OnLoaded(object sender, RoutedEventArgs e)
{
_configs = ConfigHelper.ReadConfig();
ConfigListBox.ItemsSource = _configs;
ConfigListBox.SelectionChanged += ConfigListBoxOnSelectionChanged;
}
private void ConfigListBoxOnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedConfig = ConfigListBox.SelectedItem as Config;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML:
<ListBox x:Name="ConfigListBox" Grid.Row="0" Loaded="ConfigListBox_OnLoaded">
<ListBox.ItemTemplate>
<DataTemplate DataType="MyApp:Config">
<WrapPanel>
<CheckBox Margin="0, 0, 2, 0"/>
<TextBlock Text="{Binding Name}" />
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Name="NameTextBox" Text="{Binding SelectedConfig.Name}"></TextBox>
推荐阅读
- javascript - 查找查询中的第二个赞
- java - Android studio firebase 循环遍历节点的子节点并保存在 ArrayList 中
- sql - 从 BigQuery 中的多个列中删除重复项
- python - 带有 pytest-mock 的会话范围
- java - 在 Spring boot 中使用 jsoup 进行 Web Scraping 时出现 Whitelabel 错误页面
- swift - 如果变量在数组中,则按钮标签不刷新
- reactjs - 在页面呈现之前使用 fetch 设置状态
- java - 使用 EmbeddedId 更新 ElementCollection 时出现反射错误
- flask - 烧瓶 sqlalchemy 处理数据库中的关系
- python - 寻找一种更快的方法来根据另一列中的值移动熊猫数据框列中的值