WPF数据绑定无法通过XAML工作(仅通过代码)

时间:2014-01-14 21:02:16

标签: c# wpf xaml data-binding

尝试通过ListViewObservableCollection绑定到XAML时,ListView未更新,并且最初加载了空值。

通过XAML

History.xaml.cs

DataContext = this;

History.xaml:

<ListView x:Name="lvHistory" ItemsSource="{Binding Source=history}" BorderThickness="0" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2" util:GridViewSort.AutoSort="True" SizeChanged="lvHistory_SizeChanged">

通过CODE

通过代码进行绑定时,绑定正常工作。

History.xaml

<ListView x:Name="lvHistory" BorderThickness="0" Margin="0,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2" util:GridViewSort.AutoSort="True" SizeChanged="lvHistory_SizeChanged">

History.xaml.cs

DataContext = this;
lvHistory.ItemsSource = history;

只需通过代码添加ItemsSource并在XAML中删除它,代码就可以正常工作。我错过了什么?如何通过纯XAML创建绑定?

历史:

public ObservableCollection<LocateElement> history { get; private set; }

更新清单的代码:

    public void Update()
    {
        if (updater.IsBusy) updatePending = true;
        else
        {
            searchValue = txtSearch.Text.Trim();
            updatePending = false;
            updater.RunWorkerAsync();
        }
    }

    private void updateContent(object sender, DoWorkEventArgs e)
    {
        try
        {
            Globals.Variables.logger.Info("Locate History: Updating");

            using (var db = new Data.DataManager())
            {
                var history = db.LocateHistory.Where(o => o.ReceivedBy == Globals.Variables.loginDetails.UserID);

                e.Result = filterResults(history);
            }

        }
        catch (Exception er)
        {
            Globals.Variables.logger.Error(er);
        }
    }

    private void updateFinished(object sender, RunWorkerCompletedEventArgs e)
    {
        List<LocateElement> r = (List<LocateElement>)e.Result;

        history.Clear();
        foreach (LocateElement l in r)
        {
            history.Add(l);
        }

        if (updatePending) Update();
        //else Wpf.Util.GridViewSort.ReapplySort(lvHistory);
    }

    private List<LocateElement> filterResults(IQueryable<LocateElement> list)
    {
        List<LocateElement> history = new List<LocateElement>();

        foreach (LocateElement l in list)
        {
            if (searchValue != "")
            {
                // Use the parameters to filter the results.
                Regex reg = new Regex(WildcardToRegex(searchValue));


                if (reg.IsMatch(l.Serial) || reg.IsMatch(l.Asset) || reg.IsMatch(l.DeviceType) || reg.IsMatch(l.Company) || (l.ReceivedFrom != null && reg.IsMatch(l.ReceivedFrom.Name)) || (l.ReceivedTo != null && reg.IsMatch(l.ReceivedTo.Name)) || reg.IsMatch(l.Row) || reg.IsMatch(l.Shelf) || reg.IsMatch(l.Bin) || reg.IsMatch(l.DateReceived.ToString()))
                {
                    history.Add(l);
                }
            }
            else
            {
                history.Add(l);
            }
        }

        return history;
    }

2 个答案:

答案 0 :(得分:2)

将数据分配给历史记录集时,需要确保引发属性更改事件。

例如:

    public class MyViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private ObservableCollection<LocateElement> _history;

        public ObservableCollection<LocateElement> history 
        {
            get { return _history; }
            set
            {
                if (_history != value)
                {
                    _history = value;

                    RaisePropertyChanged("history");
                }
            }
        }

        public MyViewModel()
        {
            _history = new ObservableCollection<LocateElement>();
        }

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

答案 1 :(得分:1)

Source的{​​{1}}属性并不代表您认为的含义。请改为使用Binding或假设您正在谈论Path(默认)。这应该做到。

Path

此外,如果您设置构造函数之外的<ListView ItemsSource="{Binding history}" ...> 属性,则需要通知属性已更改。如果您只是在构造函数中设置它,则不需要,但您可能希望由history字段而不是自动getter / setter支持。 (TrueEddie的解决方案描述了这个问题并提供了能够交换实际变量的解决方案。)