windows - 更新和过滤列表选择器

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

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

2 列表选择器 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 代码进行数据绑定(bind)

    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; }
        }
    }

最佳答案

与其将 ListPickers 数据绑定(bind)到完全相同的列表,不如尝试创建 2 个代理属性来控制对基础列表的访问。然后,您可以让代理属性的 getter 过滤掉为其他列表选择的任何内容(假设选择的对象也绑定(bind)到 View 模型。或者(或可能另外)您可以使用 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; }
}

关于windows - 更新和过滤列表选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6562379/

相关文章:

c++ - (C/C++) Windows 7 中的 EOF

python - Pyinstaller 创建的 exe 在一台机器上运行,但在另一台机器上出错

wcf - 即使在调用 'void' 异步方法时,后退按钮上的“WebException”错误

c# - 调用 try 中的方法时未捕获异常?

windows - TortoiseSVN - 在共享 Mac 文件夹上的 Windows 10 虚拟机中没有覆盖图标

c++ - SDL 应用程序无法在其他计算机上运行

c# - 应用挂起我的 Windows Phone 7 手机

c# - Windows Phone的系统服务

xaml - Silverlight 中控件的占位符