更新和过滤列表选择器

发布于 2024-11-18 06:30:37 字数 2910 浏览 0 评论 0原文

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

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 代码进行数据绑定

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

I have two list pickers with same databinding(from XML), When first listpicker have selection changed it should filter data of second listpicker and hide item which selected in first listpicker, same as second 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>

DataBinding with XML code

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘦怹 2024-11-25 06:30:37

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

Rather than databind the ListPickers to the exact same list try creating 2 proxy properties which control access to the underlying list. You could then have the getter for the proxy properties filter out whatever has been selected for the other list (assuming that the sleected object is also bound to the viewmodel. Alternatively (or possibly in addition) you could use the SelectionChanged event to force the updating to the proxy lists.

Update
Here's an example:

Assuming a page contains this:

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

The code behind should look like this:

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; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文