【问题标题】:Rules of binding an object in wpfwpf中绑定对象的规则
【发布时间】:2012-10-12 14:14:22
【问题描述】:

我很难将ListView 与另一个班级的ObservableCollection 绑定。

我的xml:

<ListView Height="117" HorizontalAlignment="Left" Margin="20,239,0,0" Name="lvResults" VerticalAlignment="Top" Width="759" ItemsSource="{Binding RuleSearch.FileMatches}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding FileName}"/>
                <GridViewColumn Header="Size" Width="120" DisplayMemberBinding="{Binding DirectoryName}"/>
                <GridViewColumn Header="Date" Width="120" DisplayMemberBinding="{Binding Size}"/>
                <GridViewColumn Header="Full Path" Width="120" />
                <GridViewColumn Header="Some Meaningless Data" Width="120" />
            </GridView>
        </ListView.View>
    </ListView>

代码背后的 Xaml:

private Search _ruleSearch = new Search();
public Search RuleSearch { get { return _ruleSearch; }}

在搜索类中:

public ObservableCollection<Result> FileMatches { get; private set; }

请注意,更改是在新线程上进行的,如果有影响的话:

private void FindResultOnNewThreads()
  {
     FileMatches.Clear();

     Parallel.ForEach(_fileList, file =>
     {
        foreach (Regex search in SearchTermList.Where(search => search.IsMatch(file)))
        {
           lock (FileMatches)
           {
              FileInfo fileInfo = new FileInfo(file);
              FileMatches.Add(new Result
                                 {
                                    Attributes = fileInfo.Attributes,
                                    DirectoryName = fileInfo.DirectoryName,
                                    Extension = fileInfo.Extension,
                                    FileName = fileInfo.Name,
                                    FullNamePath = fileInfo.FullName,
                                    Size = fileInfo.Length
                                 });
           }
        }
     });
  }

结果类:

    public class Result
   {
      public string FileName { get; set; }
      public string DirectoryName { get; set; }
      public string FullNamePath { get; set; }
      public long Size { get; set; }
      public string Extension { get; set; }
      public FileAttributes Attributes { get; set; }

   }

问题确实是,我正在自己学习 wpf,但实际上找不到 WPF 中数据绑定的规则集。我知道它需要属性和公共属性,除了我被卡住了。

【问题讨论】:

  • 您说您遇到了困难,请具体说明问题所在。如果有的话,你在哪里设置 DataContext?
  • @BigDaddy,我以为我指定的问题是我无法绑定。我在 xaml 中绑定 DataContext:ItemsSource="{Binding RuleSearch.FileMatches}" 我什至尝试了几个不同的变体。一个在后面的代码中...

标签: c# wpf binding


【解决方案1】:

可能您的 listViews DataContext 未设置为 UserControls 或 Windows 或其他您拥有 RuleSearch 道具的地方。

您可以在 xaml.cs 代码隐藏中设置它。

lvResult.DataContext = this;

或在 xaml 中

<ListView Height="117" HorizontalAlignment="Left" Margin="20,239,0,0" Name="lvResults" VerticalAlignment="Top" Width="759" ItemsSource="{Binding Path=RuleSearch.FileMatches, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding FileName}"/>
            <GridViewColumn Header="Size" Width="120" DisplayMemberBinding="{Binding DirectoryName}"/>
            <GridViewColumn Header="Date" Width="120" DisplayMemberBinding="{Binding Size}"/>
            <GridViewColumn Header="Full Path" Width="120" />
            <GridViewColumn Header="Some Meaningless Data" Width="120" />
        </GridView>
    </ListView.View>
</ListView>

其中 typeOfAncestor 是您的用户控件/窗口的类型...

【讨论】:

  • 我之前尝试过的代码隐藏不起作用。我刚刚尝试了您的 xaml 部分,似乎我得到了一些东西。好吧,我认为这很好,因为我在 ObservableCollection 上收到一个错误,说明我不能再在不同的线程上更改它的值了。
  • 巴洛格,天才!如果我把它从不同的线程上取下来,它会起作用......不过我有两个问题:1-你能把我链接到我可以了解更多关于那段 xaml 代码的地方吗? 2-无论如何我可以把它放在另一个线程上?因为我要求不要有滞后。
  • thisthis
  • 您可以使用 Dispatcher.Invoke 在另一个线程上执行此操作。请参阅this 答案。
【解决方案2】:

您的Search 类需要实现INotifyPropertyChanged,它用于让UI 知道代码隐藏中的属性何时发生变化(在本例中为FileMatches)。这将涉及注册对FileMatches.CollectionChanged 事件的回调,然后引发属性名为“FileMatches”的INotifyPropertyChanged.PropertyChanged 事件。

请注意,如果您希望集合中的值与 UI 保持同步,您还应该在 Result 类上实现 INotifyPropertyChanged。 (通过查看您的代码,您的 Result 类的内容看起来是不变的,因此您不需要这样做)。

【讨论】:

  • 不幸的是,我之前尝试过,但也无法正常工作。不过谢谢。
  • 没有 INotifyPropertyChanged 的​​唯一方法是在 UI 需要显示自己之前数据已准备好。如果它碰巧在没有 INotifyPropertyCHanged 的​​情况下工作,你可能会很幸运,并且你的线程外任务恰好在 UI 显示之前完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2011-04-24
  • 2012-07-03
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
相关资源
最近更新 更多