WPF打开文件并更新窗口

时间:2018-08-07 17:25:03

标签: c# wpf checkbox data-binding checkboxlist

我对WPF比较陌生。我正在尝试打开一个excel文件并拉出列标题,并将其作为检查列表显示在我的窗口中。现在,我在更新窗口/清单时遇到问题。

这是我在xaml中拥有的

    <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;
    private Excel.Workbook xlWorkbook;
    public ObservableCollection<TagClass> TagListData { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        ...

        TagListData = new ObservableCollection<TagClass>();
    }

    private void btnOpenFile_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.slxm";
        if (openFileDialog.ShowDialog() == true)
        {
            xlApp = new Excel.Application();
            xlWorkbook = xlApp.Workbooks.Open(openFileDialog.FileName);

            //populate TagListData
            TagListData.Add(new TagClass { IsTagSelected = true, TagName = "Tag Name 1" });

        }
    }

    public class TagClass
    {
        public string TagName { get; set; }
        public bool IsTagSelected { get; set; }

    }    

当我尝试打开文件填充我的清单时,什么也没有发生。有人知道我在做什么吗?

我还发现了此功能,它可以检查项目何时更新,但是我想检查列表/集合何时更新。我很难解决这个问题。ListBox item doesn't get refresh in WPF?

谢谢

2 个答案:

答案 0 :(得分:1)

您似乎尚未设置窗口的DataContext。数据上下文是您要绑定的东西,它不仅会自动绑定到添加到窗口本身的属性上。

有很多方法可以解决此问题,最简单(但可以说是错误的)的解决方法是将其添加到构造函数的末尾:

this.DataContext = this;

但这很奇怪。我建议不要这样做。通常,我们创建一个新对象来容纳我们要绑定到的数据。在这种情况下,可以将DataContext设置为TagListData,然后相应地更新绑定。

public MainWindow()
{
    InitializeComponent();
    ...

    TagListData = new ObservableCollection<TagClass>();
    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>

如果要在Window上绑定其他内容,则无法将DataContext设置为集合。相反,您应该创建一个新类,其中将包含该集合以及要绑定到的所有其他内容。添加此新类的类型的属性,并将其设置为窗口的DataContext。当您使用MVVM模式时,通常将其称为ViewModel。

答案 1 :(得分:1)

同意尼克;此外,如果您不处理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>

在后面的代码中

private void btnOpenFile_Click(object sender, RoutedEventArgs e)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.slxm";
                if (openFileDialog.ShowDialog() == true)
                {
                    xlApp = new Microsoft.Office.Interop.Excel.Application();
                    xlWorkbook = xlApp.Workbooks.Open(openFileDialog.FileName);

                    //populate TagListData
                    TagListData.Add(new TagClass { IsTagSelected = true, TagName = "Tag Name 1" });
                }

                TagList.ItemsSource = TagListData;
            }