更新和过滤listpicker

时间:2011-07-03 10:35:47

标签: windows windows-phone-7 silverlight-4.0 silverlight-toolkit

我有两个具有相同数据绑定的列表选择器(来自XML),当第一个listpicker更改了选择时,它应该过滤第二个listpicker的数据并隐藏在第一个listpicker中选择的项目,与第二个listpicker相同。

2 listpicker XAML ......

<my:ListPicker HorizontalAlignment="Left" 
                        x:Name="listPicker1" Width="265" BorderBrush="{x:Null}" FontFamily="Segoe UI" FontSize="18.667" Background="{StaticResource PhoneTextBoxBrush}" ScrollViewer.VerticalScrollBarVisibility="Visible" Margin="147,0,0,0" Grid.Row="1" Foreground="#FF1BA1E2" Height="35" SelectionChanged="listPicker1_SelectionChanged" >
                        <my:ListPicker.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Width="360" Height="34">
                                    <TextBlock x:Name="item" Text="{Binding ChannelName, Mode=TwoWay}" FontSize="18.667" Margin="12, 0, 2, 2" />
                                </StackPanel>
                            </DataTemplate>
                        </my:ListPicker.ItemTemplate>
                    </my:ListPicker>
                    <TextBlock TextWrapping="Wrap" FontFamily="Segoe UI" FontSize="16" Margin="52,5,0,5" Grid.Row="3" HorizontalAlignment="Left" Width="91" Text="Channel 2 "/>
                    <my:ListPicker HorizontalAlignment="Left" 
                        x:Name="listPicker2" Width="265" BorderBrush="{x:Null}" FontFamily="Segoe UI" FontSize="18.667" Background="{StaticResource PhoneTextBoxBrush}" Foreground="#FF1BA1E2" ScrollViewer.VerticalScrollBarVisibility="Visible" Margin="147,0,0,0" Grid.Row="3" SelectionChanged="listPicker2_SelectionChanged" >
                        <my:ListPicker.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Width="360" Height="34">
                                    <TextBlock x:Name="item" Text="{Binding ChannelName, Mode=TwoWay}" FontSize="18.667" Margin="12, 0, 2, 2" />
                                </StackPanel>
                            </DataTemplate>
                        </my:ListPicker.ItemTemplate>
                    </my:ListPicker>

使用XML代码的DataBinding

    public Customize()
    {
        InitializeComponent();

        XDocument loadedData = XDocument.Load("newsChannels.xml");

        var channels = from query in loadedData.Descendants("channel")
                       select new Channels
                       {
                           ChannelName = (string)query.Element("channelname"),
                       };
        listPicker1.ItemsSource = channels;
        listPicker2.ItemsSource = channels;
    }

    public class Channels
    {
        string channelname;

        public string ChannelName
        {
            get { return channelname; }
            set { channelname = value; }
        }
    }

1 个答案:

答案 0 :(得分:1)

不是将ListPickers数据绑定到完全相同的列表,而是尝试创建2个控制对基础列表的访问的代理属性。然后,您可以使用代理属性的getter过滤掉为其他列表选择的任何内容(假设sleected对象也绑定到viewmodel。或者(或可能另外),您可以使用SelectionChanged事件强制更新到代理列表。

<强>更新 这是一个例子:

假设一个页面包含:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel>
        <toolkit:ListPicker x:Name="picker1" 
                            ItemsSource="{Binding List1, Mode=TwoWay}"
                            SelectedItem="{Binding SelectedItem1, Mode=TwoWay}" 
                            SelectionChanged="ListPicker1SelectionChanged" />
        <toolkit:ListPicker x:Name="picker2"
                            ItemsSource="{Binding List2, Mode=TwoWay}"
                            SelectedItem="{Binding SelectedItem2, Mode=TwoWay}"
                            SelectionChanged="ListPicker2SelectionChanged" />
    </StackPanel>
</Grid>

背后的代码应如下所示:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        this.DataContext = new TwoListViewModel();
    }

    private void ListPicker1SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Ensure that the selected Item is updated
        picker1.GetBindingExpression(ListPicker.SelectedItemProperty).UpdateSource();

        // rebind the other list
        var binding = picker2.GetBindingExpression(ListPicker.ItemsSourceProperty).ParentBinding;
        picker2.SetBinding(ListPicker.ItemsSourceProperty, binding);
    }

    private void ListPicker2SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        picker2.GetBindingExpression(ListPicker.SelectedItemProperty).UpdateSource();

        var binding = picker1.GetBindingExpression(ListPicker.ItemsSourceProperty).ParentBinding;
        picker1.SetBinding(ListPicker.ItemsSourceProperty, binding);
    }
}

public class TwoListViewModel
{
    public TwoListViewModel()
    {
        // MUST Initialize the selected items
        SelectedItem1 = "one";
        SelectedItem2 = "two";
    }

    private IEnumerable<string> InnerList
    {
        get
        {
            return new[]
                   {
                       "one",
                       "two",
                       "three",
                       "four",
                       "five",
                   };
        }
    }

    public IEnumerable<string> List1
    {
        get
        {
            return InnerList.Where(item => item != SelectedItem2);
        }
    }

    public IEnumerable<string> List2
    {
        get
        {
            return InnerList.Where(item => item != SelectedItem1);
        }
    }

    public string SelectedItem1 { get; set; }

    public string SelectedItem2 { get; set; }
}