绑定到列表中的当前项

时间:2013-03-26 02:11:15

标签: wpf data-binding

所以我在这里有这个xaml

<ListBox Grid.Column="1" Grid.Row="1" Background="Transparent" ItemsSource="{Binding Packages}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <gameManagement:FeedGame DataContext="{Binding}" Package="{Binding Path=/}"></gameManagement:FeedGame>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

一个名为DependencyProperty

Package的UserControl

我要做的是将该属性设置为列表中的当前项。我现在已经在这里待了大约一个小时,不知道我做错了什么。

我上面的当前代码抛出FirstChanceException

BindingExpression path error: '' property not found on 'current item of collection' ''FeedGame' (Name='Me')'. BindingExpression:Path=/; DataItem='FeedGame' (Name='Me'); target element is 'FeedGame' (Name='Me'); target property is 'Package' (type 'IPackage')

如果你很好奇Me是什么,这是在UserControl的xaml中,上面的列表框包含在

x:Name="Me"
DataContext="{Binding ElementName=Me}"

这是FeedGame

public static readonly DependencyProperty PackageProperty = DependencyProperty.Register(
        "Package", typeof(IPackage), typeof(FeedGame));

public IPackage Package {
    get
    {
        return (IPackage)this.GetValue(PackageProperty);
        //return this.package;
    }
    set
    {
        // Setter here never gets called.
        if (Equals(value, (IPackage)this.GetValue(PackageProperty)))
        {
            return;
        }
        SetValue(PackageProperty,value);
        this.OnPropertyChanged("Package");
    }
}

1 个答案:

答案 0 :(得分:0)

当您填充Package时,setter不会被调用,因为绑定引擎直接调用GetValueSetValue(绕过属性Set和Get)。

如果你需要在setter中做一些逻辑并且你正在使用绑定,你可以使用PropertyChangedCallback

示例:

     public static readonly DependencyProperty PackageProperty = DependencyProperty.Register(
     "Package", typeof(IPackage), typeof(FeedGame), new UIPropertyMetadata(null, new PropertyChangedCallback(OnPackageChanged)));

     // callback when value changed
     private static void OnPackageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
         if (Equals(e.OldValue, e.NewValue))
         {
             return;
         }
     }

     public IPackage Package
     {
         get { return (IPackage)this.GetValue(PackageProperty); }
         set { SetValue(PackageProperty, value); }
     }

编辑:

我的测试

的Xaml:

<Window x:Class="WpfApplication10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:local="clr-namespace:WpfApplication10"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="199" Width="191" Name="UI">
    <Grid DataContext="{Binding ElementName=UI}"> 
        <ListBox ItemsSource="{Binding Packages}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                     <local:FeedGame Package="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

代码:

namespace WpfApplication10
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Packages.Add(new Package());
            Packages.Add(new Package());
            Packages.Add(new Package());
        }

        private ObservableCollection<IPackage> _packages = new ObservableCollection<IPackage>();
        public ObservableCollection<IPackage> Packages
        {
            get { return _packages; }
            set { _packages = value; }
        }
    }

    public class FeedGame : FrameworkElement
    {
        public static readonly DependencyProperty PackageProperty = 
            DependencyProperty.Register( "Package", typeof(IPackage), typeof(FeedGame)
            , new UIPropertyMetadata(null, new PropertyChangedCallback(OnPackageChanged)));

         private static void OnPackageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             if (Equals(e.OldValue, e.NewValue))
             {
                 return;
             }
         }

         public IPackage Package
         {
             get { return (IPackage)this.GetValue(PackageProperty); }
             set { SetValue(PackageProperty, value); }
         }
    }

    public interface IPackage { }

    public class Package : IPackage { }
}