C# WPF打开文件并更新窗口
我对WPF比较陌生。我正试图打开一个excel文件,拉取列标题,并将其显示在我的窗口中作为检查列表。现在我在更新我的窗口/清单时遇到问题 这是我在xaml中的内容C# WPF打开文件并更新窗口,c#,wpf,checkbox,data-binding,checkboxlist,C#,Wpf,Checkbox,Data Binding,Checkboxlist,我对WPF比较陌生。我正试图打开一个excel文件,拉取列标题,并将其显示在我的窗口中作为检查列表。现在我在更新我的窗口/清单时遇到问题 这是我在xaml中的内容 <DockPanel Grid.Column="0" Grid.Row="1" Margin="10"> <ListBox ItemsSource="{Binding TagListData}"> <ListBox.ItemTemplate>
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<ListBox ItemsSource="{Binding TagListData}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
这是我在cs代码中的内容。(我现在只使用一个占位符,而不是阅读打开的excel文档,以查看我是否正确地执行了此操作。)
private Excel.Application xlApp;
私人Excel工作簿;
公共ObservableCollection TagListData{get;set;}
公共主窗口()
{
初始化组件();
...
TagListData=新的ObservableCollection();
}
私有无效btnOpenFile_单击(对象发送方,路由目标)
{
OpenFileDialog OpenFileDialog=新建OpenFileDialog();
openFileDialog.Filter=“Excel文件|*.xls;*.xlsx;*.slxm”;
if(openFileDialog.ShowDialog()==true)
{
xlApp=new Excel.Application();
xlWorkbook=xlApp.Workbooks.Open(openFileDialog.FileName);
//填充TagListData
TagListData.Add(新标记类{IsTagSelected=true,TagName=“标记名1”});
}
}
公共类标记类
{
公共字符串标记名{get;set;}
公共布尔值{get;set;}
}
当我试图打开一个文件来填充我的清单时,什么都没有发生。有人知道我做错了什么吗
我还发现它可以检查项目何时更新,但我想检查列表/集合何时更新。我很难弄明白这一点
谢谢看起来您还没有设置窗口的DataContext。数据上下文是您绑定到的对象,它不只是自动将绑定连接到您添加到窗口本身的属性 有很多方法可以解决这个问题,最简单(但可能是错误的)解决方法是将其添加到构造函数的末尾:
this.DataContext = this;
但这很奇怪。我建议永远不要这样做。我们通常会创建一个新对象来存放我们想要绑定到的数据。在这种情况下,可以将DataContext设置为TagListData,然后相应地更新绑定
public MainWindow()
{
InitializeComponent();
...
TagListData = new ObservableCollection<TagClass>();
this.DataContext = TagListData;
}
public主窗口()
{
初始化组件();
...
TagListData=新的ObservableCollection();
this.DataContext=TagListData;
}
并更新绑定
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<ListBox ItemsSource="{Binding}"> <!-- note no Path on this binding because the data context of the window IS the collection now -->
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
如果要在窗口上绑定其他内容,则将DataContext设置为集合将不起作用。相反,您应该创建一个新类,该类将包含集合和所有其他要绑定到的对象。添加此新类类型的属性,并将其设置为窗口的DataContext。当您使用MVVM模式时,这通常是我们所说的ViewModel。看起来您还没有设置窗口的DataContext。数据上下文是您绑定到的对象,它不只是自动将绑定连接到您添加到窗口本身的属性 有很多方法可以解决这个问题,最简单(但可能是错误的)解决方法是将其添加到构造函数的末尾:
this.DataContext = this;
但这很奇怪。我建议永远不要这样做。我们通常会创建一个新对象来存放我们想要绑定到的数据。在这种情况下,可以将DataContext设置为TagListData,然后相应地更新绑定
public MainWindow()
{
InitializeComponent();
...
TagListData = new ObservableCollection<TagClass>();
this.DataContext = TagListData;
}
public主窗口()
{
初始化组件();
...
TagListData=新的ObservableCollection();
this.DataContext=TagListData;
}
并更新绑定
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<ListBox ItemsSource="{Binding}"> <!-- note no Path on this binding because the data context of the window IS the collection now -->
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
如果要在窗口上绑定其他内容,则将DataContext设置为集合将不起作用。相反,您应该创建一个新类,该类将包含集合和所有其他要绑定到的对象。添加此新类类型的属性,并将其设置为窗口的DataContext。当您使用MVVM模式时,这通常就是我们所说的ViewModel。同意Nick的观点;此外,如果不处理
Datacontext
和使用代码隐藏,则使用Name
属性来标识列表框并在代码隐藏中设置ItemsSource
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<!-- Note here-->
<ListBox Name="TagList">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
同意尼克的观点;此外,如果不处理
Datacontext
和使用代码隐藏,则使用Name
属性来标识列表框并在代码隐藏中设置ItemsSource
<DockPanel Grid.Column="0" Grid.Row="1" Margin="10">
<!-- Note here-->
<ListBox Name="TagList">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsTagSelected}" Content="{Binding TagName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
非常感谢您,它现在似乎正在按预期工作。INotifyPropertyChanged是否不是更新集合所必需的?这取决于集合和更新的内容。如果使用的是ObservableCollection,则向集合中添加或删除项时不需要INotifyPropertyChanged。如果要用可观察集合的新实例替换集合,则需要INotifyPropertyChange。如果除了选中UI上的复选框之外,还有其他方法可以更改单个项目的标记名或IsTagSelected,那么您的标记类将需要实现InotifyPropertyChange非常感谢,它现在似乎可以正常工作。INotifyPropertyChanged是否不是更新集合所必需的?这取决于集合和更新的内容。如果使用的是ObservableCollection,则向集合中添加或删除项时不需要INotifyPropertyChanged。如果要用可观察集合的新实例替换集合,则需要INotifyPropertyChange。如果有办法更改标记名或IsTag