【问题标题】:WPF Opening a file and updating windowWPF 打开文件并更新窗口
【发布时间】:2018-08-07 17:25:02
【问题描述】:

我对 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?

谢谢

【问题讨论】:

    标签: c# wpf checkbox data-binding checkboxlist


    【解决方案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。

    【讨论】:

    • 非常感谢,它现在似乎正在按预期工作。更新集合不需要 INotifyPropertyChanged 吗?
    • 这取决于收藏和更新内容。如果您使用的是 ObservableCollection,则不需要 INotifyPropertyChanged 来向集合中添加或删除项目。如果您打算用可观察集合的新实例替换集合,则需要 INotifyPropertyChange。如果除了选中 UI 上的复选框之外还有其他方法可以更改单个项目的 TagName 或 IsTagSelected,那么您的 TagClass 将需要实现 INotifyPropertyChange
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多