绑定不起作用但也不会产生任何错误

时间:2011-04-05 20:54:50

标签: c# .net wpf sorting binding

我想让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 ( );
        }
    }
}

没有编译错误或运行时错误,列表视图为空。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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