我无法获得自定义控件的选定项目

时间:2015-10-12 10:11:50

标签: c# wpf xaml mvvm binding

Pager.xaml(查看)

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="Client.View.Pager">
    ...
    <ListBox x:Name="listBoxEntries"
             ItemsSource="{Binding Path=ListCollectionView}"
             BorderThickness="0"
             Margin="0"
             Style="{StaticResource common}"
             HorizontalContentAlignment="Stretch"
             VerticalContentAlignment="Stretch"
             ItemTemplate="{StaticResource templateTableCategory}"
             SelectedItem="{Binding Path=SelectedEntry, Mode=TwoWay}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="{Binding Path=Rows}"
                             Columns="{Binding Path=Columns}"
                             IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
    ...
</Grid>

Pager.xaml.cs(代码背后)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Client.Model;
using Client.ViewModel;

namespace Client.View
{
    public partial class Pager
    {
        public static readonly DependencyProperty SelectedEntryProperty = DependencyProperty.Register("SelectedEntry", typeof(IPagableEntry), typeof(Pager));
        ...
        public IPagableEntry SelectedEntry
        {
            get { return (DataContext as PagerViewModel).SelectedEntry; }
            set { (DataContext as PagerViewModel).SelectedEntry = value; }
        }
        ...
    }
}

PagerViewModel.cs

namespace Client.ViewModel
{
    public class PagerViewModel : ViewModelBase
    {
        ...

        IPagableEntry _selectedEntry;
        public IPagableEntry SelectedEntry
        {
            get
            {
                return _selectedEntry;
            }

            set
            {
                _selectedEntry = value;
                OnPropertyChanged("SelectedEntry");
            }
        }
        ...
    }
}

MainPage.xaml中(查看)

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="Client.View.MainPage"
      Style="{StaticResource common}">
    <Page.DataContext>
        <viewModel:MainPageViewModel/>
    </Page.DataContext>
    ...

    <view:Pager x:Name="pagerTableCategories"
            Grid.Row="0"
            List="{Binding Path=PagerTableCategoriesItems}"
            Rows="{Binding Path=PagerTableCategoriesRows}"
            Columns="{Binding Path=PagerTableCategoriesColumns}"
            SelectedEntry="{Binding Path=SelectedTableCategory, Mode=TwoWay}">
    </view:Pager>
    ...
</Page>

MainPageViewModel.cs

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Client.Model;

namespace Client.ViewModel
{
    public class MainPageViewModel : ViewModelBase
    {
        ...
        IPagableEntry _selectedTableCategory;

        public IPagableEntry SelectedTableCategory
        {
            get
            {
                return _selectedTableCategory;
            }
            set
            {
                _selectedTableCategory = value;
                MessageBox.Show("Got it!");
            }
        }
        ...
    }
}

我制作了一个自定义面板'Pager',那就是ViewModel。 我想在我的MainPage中显示寻呼机。 我希望我选择一个项目,然后MainPageViewModel的属性SelectTableCategory将更改,并显示一个消息框,其中包含字符串“Got it!” 但它不起作用...... 我的问题是什么?

PS。我不是很擅长英语。 我很感激你的理解。

1 个答案:

答案 0 :(得分:0)

让我们从第一原则开始工作。

您有一个名为Pager的自定义控件,可以像这样使用

<view:Pager x:Name="pagerTableCategories"
        SelectedEntry="{Binding Path=SelectedTableCategory, Mode=TwoWay}">
</view:Pager>

查看SelectedEntry如何分配绑定?这告诉我们,Pager必须将SelectedEntry实现为依赖属性。我们怎么做?

public class Pager
{
    // Using a DependencyProperty as the backing store for PrePend.  
    //   This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedEntryProperty =
        DependencyProperty.Register("SelectedEntry", typeof(object), 
          typeof(Pager), 
          new PropertyMetadata(null, OnSelectedEntryChanged));

    public object SelectedEntry
    {
         get { return GetValue(SelectedEntryProperty); }
         set { SetValue(SelectedEntryProperty, value); }
    }

    private static void OnSelectedEntryChanged(DependencyObject pager, DependencyPropertyChangedEventArgs e) 
    {
         // TODO set the SelectedItem in the ListBox
    }
}

接下来,您需要显示寻呼机。你的XAML看起来不错。您应该在ListBox上添加一个事件处理程序来侦听选择已更改的事件。这样,您可以在发生这种情况时更新SelectedEntry

public class Pager
{
    // continued...

    // *Updated*
    private listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.SelectedEntry = (sender as ListBox).SelectedItem;
    }
}