绑定不起作用,但也不会给出任何错误

问题描述:

我试图让this code(来自博客)工作。绑定不起作用,但也不会给出任何错误

下载文件在那里不可用,所以我复制了代码片段,它似乎工作,除了我不得不组成一个绑定,但项目不显示。

有关如何解决此问题的任何想法?听起来像是我失踪的小事。

<Window x:Class="WpfMultiColumnSorting.SortWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="SortWindow" Height="300" Width="600"> 
    <ListView Name="DashListView" ItemsSource="{Binding SortedItems}"> 

     <ListView.View> 
      <GridView> 
       <GridViewColumn Width="95" DisplayMemberBinding="{Binding Name}"> 
        <GridViewColumnHeader Click="SortClick" Tag="Name" Content="Name" /> 
       </GridViewColumn> 

       <GridViewColumn Width="90"> 
        <GridViewColumnHeader Click="SortClick" Tag="IsActive" Content="Activitation" /> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal" ToolTip="{Binding IsActive}"> 
           <TextBlock Name="ActivityStatusText" Text="{Binding IsActive}"></TextBlock> 
          </StackPanel> 
          <DataTemplate.Triggers> 
           <DataTrigger Binding="{Binding IsActive}" Value="true"> 
            <Setter TargetName="ActivityStatusText" Property="FontWeight" Value="Bold" /> 
           </DataTrigger> 
          </DataTemplate.Triggers> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 

       <GridViewColumn Width="140" DisplayMemberBinding="{Binding CreationDate}"> 
        <GridViewColumnHeader Click="SortClick" Tag="CreationDate" Content="Created On" /> 
       </GridViewColumn> 

       <GridViewColumn Width="85" DisplayMemberBinding="{Binding Value}"> 
        <GridViewColumnHeader Click="SortClick" Tag="Value" Content="Value #" /> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 
</Window> 





using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.ComponentModel; 
using System.Globalization; 
using System.Collections.ObjectModel; 

namespace WpfMultiColumnSorting 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 

    public partial class SortWindow : Window 
    { 
     ObservableCollection<SortedItemViewModel> sortedItems; 
     public ObservableCollection<SortedItemViewModel> SortedItems 
     { 
      get { return this.sortedItems; } 
      set 
      { 
       this.sortedItems = value; 
       this.RaisePropertyChanged ("SortedItems"); 
      } 
     } 

     public SortWindow () 
     { 
      this.SortedItems = new ObservableCollection<SortedItemViewModel> (); 

      this.SortedItems = new ObservableCollection<SortedItemViewModel> () { 
       new SortedItemViewModel ("A", false, DateTime.Now, "1"), 
       new SortedItemViewModel ("B", false, DateTime.Now, "2"), 
       new SortedItemViewModel ("C", false, DateTime.Now, "3"), 
       new SortedItemViewModel ("D", false, DateTime.Now, "4"), 
       new SortedItemViewModel ("E", false, DateTime.Now, "5"), 
       new SortedItemViewModel ("F", false, DateTime.Now, "6"), 
       new SortedItemViewModel ("G", false, DateTime.Now, "7") 
      }; 
     } 

     #region Events 

     public event PropertyChangedEventHandler PropertyChanged; 
     void RaisePropertyChanged (string propertyName) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
       handler (this, new PropertyChangedEventArgs (propertyName)); 
     } 

     #endregion 

     private List<GridViewColumnHeader> _sortColumnStack = new List<GridViewColumnHeader> (); 

     private IDictionary<GridViewColumnHeader, SortAdorner> _adorners = new Dictionary<GridViewColumnHeader, SortAdorner> (); 


     private void SortClick (object sender, RoutedEventArgs e) 
     { 
      GridViewColumnHeader column = sender as GridViewColumnHeader; 
      ListSortDirection newDir = ListSortDirection.Ascending; 

      // Control means clear out all the prior sort stack 
      bool clear = Keyboard.Modifiers == ModifierKeys.Control; 

      PerformSort (column, newDir, clear); 
     } 


     /// <summary> 
     /// Updates the sort stack 
     /// </summary> 
     /// <param name="column">The columkn on which we are sorting</param> 
     /// <param name="newDir">The direction we should place the column sort into</param> 
     /// <param name="clear">true to clear out all curent sorting</param> 
     private void PerformSort (GridViewColumnHeader column, ListSortDirection newDir, bool clear) 
     { 
      IDictionary<GridViewColumnHeader, SortAdorner> oldAdorners = new Dictionary<GridViewColumnHeader, SortAdorner> (); 

      // determine if we are clicking an already sorted column 
      if (_sortColumnStack.Contains (column) && _adorners.ContainsKey (column)) 
      { 
       if (_sortColumnStack [ _sortColumnStack.Count - 1 ] != column) 
       { 
        // if it is not the primary use the same direction 
        newDir = _adorners [ column ].Direction; 
       } 
       else 
       { 
        // if it is the primary column then flip it 
        if (newDir == _adorners [ column ].Direction) 
         newDir = ListSortDirection.Descending; 
       } 
      } 

      // remove all the adorners so we can start a fresh 
      foreach (GridViewColumnHeader col in _adorners.Keys) 
      { 
       // save into our old adorners list 
       oldAdorners [ col ] = _adorners [ col ]; 
       // then remove it 
       AdornerLayer.GetAdornerLayer (col).Remove (_adorners [ col ]); 
      } 
      _adorners.Clear (); 

      // get rid of all the sorting 
      DashListView.Items.SortDescriptions.Clear (); 

      // Control means clear out all the prior sort stack 
      if (clear) 
      { 
       _sortColumnStack.Clear (); 
      } 
      else 
      { 
       // remove ourselves from the stack if we are in it 
       if (_sortColumnStack.Contains (column)) 
       { 
        _sortColumnStack.Remove (column); 
       } 
      } 

      // add our brand new primary one 
      _sortColumnStack.Add (column); 

      // now re-create the adorners from our stack 
      for (int i = _sortColumnStack.Count - 1; i >= 0; i--) 
      { 
       GridViewColumnHeader col = _sortColumnStack [ i ]; 
       SortAdorner adorner; 

       if (i == _sortColumnStack.Count - 1) 
       { 
        // create a new one (for the last one) 
        adorner = new SortAdorner (col, newDir, col.Tag as string, _sortColumnStack.Count - i); 
       } 
       else if (oldAdorners.ContainsKey (col)) 
       { 
        // re-use the old adorner information 
        SortAdorner oldAdorner = oldAdorners [ col ]; 
        adorner = new SortAdorner (col, oldAdorner.Direction, col.Tag as string, _sortColumnStack.Count - i); 
       } 
       else 
       { 
        // create a new one (for the last one) 
        adorner = new SortAdorner (col, newDir, col.Tag as string, _sortColumnStack.Count - i); 
       } 

       _adorners.Add (col, adorner); 
       AdornerLayer.GetAdornerLayer (col).Add (_adorners [ col ]); 
       DashListView.Items.SortDescriptions.Add (new SortDescription (
       _adorners [ col ].Field, _adorners [ col ].Direction)); 
      } 
     } 
    } 
} 





using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace WpfMultiColumnSorting 
{ 
    public class SortedItemViewModel : INotifyPropertyChanged 
    { 
     string name; 
     public string Name 
     { 
      get { return name; } 
      set 
      { 
       this.name = value; 
       this.RaisePropertyChanged ("Name"); 
      } 
     } 

     public bool IsActive { get; set; } 
     public DateTime CreationDate { get; set; } 
     public string Value { get; set; } 

     public SortedItemViewModel (string name, bool isActive, DateTime creationDate, string value) 
     { 
      this.Name = name; 
      this.IsActive = isActive; 
      this.CreationDate = creationDate; 
      this.Value = value; 
     } 

     #region Events 

     public event PropertyChangedEventHandler PropertyChanged; 
     void RaisePropertyChanged (string propertyName) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
       handler (this, new PropertyChangedEventArgs (propertyName)); 
     } 

     #endregion 
    } 
} 




using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Documents; 
using System.Windows.Media; 
using System.ComponentModel; 
using System.Windows; 
using System.Globalization; 

namespace WpfMultiColumnSorting 
{ 
    public class SortAdorner : Adorner 
    { 
     private readonly static Geometry AscGeometry = Geometry.Parse ("M 0,0 L 8,0 L 4,5 Z"); 

     private readonly static Geometry DescGeometry = Geometry.Parse ("M 0,5 L 8,5 L 4,0 Z"); 

     public ListSortDirection Direction { get; private set; } 

     public string Field { get; private set; } 

     public int SortOrder { get; private set; } 

     public SortAdorner (UIElement element, ListSortDirection dir, string field, int order) 
      : base (element) 
     { 
      Direction = dir; 
      Field = field; 
      SortOrder = order; 
     } 

     protected override void OnRender (DrawingContext drawingContext) 
     { 
      base.OnRender (drawingContext); 

      if (AdornedElement.RenderSize.Width < 20) 
       return; 

      drawingContext.PushTransform (new TranslateTransform (
      AdornedElement.RenderSize.Width - 15, (AdornedElement.RenderSize.Height - 5)/2)); 

      drawingContext.DrawGeometry (SortOrder == 1 ? Brushes.Black : Brushes.DarkGray, null, 
      Direction == ListSortDirection.Ascending ? AscGeometry : DescGeometry); 

      // annotate each arrow adorner with a number if it is not the first one 
      if (SortOrder != 1) 
      { 
       drawingContext.DrawText (new FormattedText (
       SortOrder.ToString (), CultureInfo.GetCultureInfo ("en-us"), 
       FlowDirection.LeftToRight, new Typeface ("Verdana"), 9, 
       Brushes.Black), new Point (7, 0)); 
      } 

      drawingContext.Pop (); 
     } 
    } 
} 

没有编译错误或运行时错误,并且listview为空。

+0

仔细检查输出窗口。绑定错误几乎无声无息地失败 - 但他们应该输出一些信息来表明他们失败了。 – ChrisF 2011-04-05 21:05:54

+0

我检查了它,但没有绑定表达式失败的错误打印,通常我已经见过他们很多次之前其他项目。 – 2011-04-05 21:11:46

看起来你并没有为Lis​​tView设置DataContext。创建一个名为SortWindowViewModel的新类,并将SortWindow.xaml.cs中的大部分代码移动到这个新类中。在SortWindow.xaml.cs中添加一个加载的事件处理程序,并添加 DataContext = new SortWindowViewModel(); 绑定看起来很好,它只是缺少指向那些绑定的位置。

+0

我把这个窗口添加到xaml:'DataContext =“{Binding RelativeSource = {RelativeSource Self}}”' 它的工作,非常感谢。 – 2011-04-05 21:11:11

+1

很高兴我能帮到你。如果你关注MVVM,那么你应该创建一个新的视图模型类,但如果你只是用它来玩,那么它并不重要。 – evanb 2011-04-05 21:20:52

+0

谢谢我要做你描述的东西,但并不理解这一切。我正在使用MVVM,但我认为使用SortedItemViewModel做到这一点使其成为MVVM风格。我想不是吗? – 2011-04-05 21:24:59

我不时在WPF中看到过这种情况。我不知道为什么会发生这种情况,但通常可以通过将您的数据模板移出控件并进入资源部分并通过名称或类型引用它们来解决。