【问题标题】:Cannot correctly populate ListPicker control with Image and Name无法使用 Image 和 Name 正确填充 ListPicker 控件
【发布时间】:2012-07-14 01:36:46
【问题描述】:

我为用户创建了一个 ListPicker 控件以更改其背景,但并非所有信息都正确填充到 ListPicker 控件中。当用户导航到我的 SettingsPage 时出现问题,所有 ListPicker 项目的文本都正确显示,但仅显示当前所选背景的图像。所有其他图像背景都是空白的。此外,奇怪的是,当我更改图像背景并在 MainPage 和 SettingsPage 之间来回导航时,选择的每个新图像背景都会显示在 ListPicker(以及所有其他先前选择的背景)中,而背景没有被选中的没有在 ListPicker 中显示的图像。到目前为止,我所拥有的如下:

SettingsPage.xaml

<toolkit:ListPicker x:Name="ThemeListPicker" Header="Theme" Grid.Row="2" Grid.ColumnSpan="2"
                                        SelectedIndex="{Binding}"
                                        SelectionChanged="ThemeListPicker_SelectionChanged">
                        <toolkit:ListPicker.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="{Binding Image}" Width="50" Height="37.59" Margin="0,0,12,0"/>
                                    <TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
                                </StackPanel>
                            </DataTemplate>
                        </toolkit:ListPicker.ItemTemplate>
                    </toolkit:ListPicker>

SettingsPage.xaml.cs

List<ThemeItem> themeList;

public SettingsPage()
    {
        InitializeComponent();

        themeList = new List<ThemeItem>()
        {
            new ThemeItem { Image = new BitmapImage(new Uri("Resources/Themes/PanoramaBackground.png", UriKind.Relative)), Name = "Default" },

            new ThemeItem { Image = new BitmapImage(new Uri("Resources/Themes/Abstract Pattern.jpg", UriKind.Relative)), Name = "Abstract Pattern" },
            new ThemeItem { Image = new BitmapImage(new Uri("Resources/Themes/Asian Beauty.jpg", UriKind.Relative)), Name = "Asian Beauty" },
            new ThemeItem { Image = new BitmapImage(new Uri("Resources/Themes/Autumn Leaf.jpg", UriKind.Relative)), Name = "Autumn Leaf" },                
            new ThemeItem { Image = new BitmapImage(new Uri("Resources/Themes/Old Barn.png", UriKind.Relative)), Name = "Old Barn" }
        };

        ThemeListPicker.ItemsSource = themeList;
        ThemeListPicker.DataContext = ThemeListPicker.SelectedIndex;

    }

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        //Respect the saved Theme index setting
        this.ThemeListPicker.SelectedIndex = Settings.ThemeIndex.Value;
    }

private void ThemeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count <= 0) //to eliminate IndexOutOfRangeException
        {
            return;
        }

        //string selectedItem = e.AddedItems[0] as string;
        ThemeItem selectedItem = e.AddedItems[0] as ThemeItem;

        if (selectedItem != null)
        {
            Settings.Theme.Value = selectedItem.Image.UriSource.ToString();
            Settings.ThemeIndex.Value = ThemeListPicker.SelectedIndex;
        }
    }

其中 ThemeItem 是一个小的自定义类

public class ThemeItem
{
    public BitmapImage Image { get; set; }
    public string Name { get; set; }
}

当 SettingsPage 导航到时,我如何能够正确加载 ListPicker 控件中的所有图像背景和相应的文本名称?

编辑:添加设置类信息

public class Settings
{        
    //Theme settings
    public static readonly Setting<int> ThemeIndex = new Setting<int>("ThemeIndex", 0);

    //Theme Background
    public static readonly Setting<string> Theme = new Setting<string>("Theme", "Resources/Themes/PanoramaBackground.png");
    //public static readonly Setting<BitmapImage> Theme = new Setting<BitmapImage>("Theme", new Uri("/Resources/Themes/PanoramaBackground.png", UriKind.Relative));
}

//Encapsulates a key/value pair stored in Isolated Storage ApplicationSettings
public class Setting<T>
{
    string name;
    T value;
    T defaultValue;
    bool hasValue;

    public Setting(string name, T defaultValue)
    {
        this.name = name;
        this.defaultValue = defaultValue;
    }

    public T Value
    {
        get
        {
            //Check for the cached value
            if (!this.hasValue)
            {
                //Try to get the value from Isolated Storage
                if (!IsolatedStorageSettings.ApplicationSettings.TryGetValue(
                    this.name, out this.value))
                {
                    //It has not been set yet
                    this.value = this.defaultValue;
                    IsolatedStorageSettings.ApplicationSettings[this.name] = this.value;
                }
                this.hasValue = true;
            }
            return this.value;
        }
        set
        {
            //Save the value to Isolated Storage
            IsolatedStorageSettings.ApplicationSettings[this.name] = value;
            this.value = value;
            this.hasValue = true;
        }
    }

    public T DefaultValue
    {
        get { return this.defaultValue; }
    }

    //"Clear" cached value
    public void ForceRefresh()
    {
        this.hasValue = false;
    }
}

【问题讨论】:

  • 这很奇怪。我使用您的代码重新创建了整个项目(复制粘贴,除了设置类不可用,因此我删除了使用该类的两行),所有图像都显示在列表选择器中。全部。我尝试了 pngs、jpgs、不同的文件名......仍然有效。你能帮我分享一下设置类吗(至少是重要的部分),这样我也可以测试一下吗?
  • 不过,当我添加设置类时,一切正常。对于列表中的每个项目,都会显示所有图像。您对这些图像的构建操作是什么?图片的尺寸是多少?我正在抛出想法,也许会出现一些事情。
  • 谢谢。构建操作是资源,大多数图像大小约为 1024x768,尽管图像被调整为 ListPicker 为 50*37.59 以保持大致 4:3 的纵横比以模拟用作背景时照片的实际大小。
  • 我注意到,由于我有大约 100 个项目,我的 ListPicker 正在加载到一个新页面,这很好,虽然图像根本没有显示,只有文本,虽然文本不是背景的名称,而是ApplicationName.Views.ThemeItem。最好只创建一个 ListBox 并使用主题填充它,或者使用 LongListSelector 代替。如果是这样,最好的实现是什么(我的列表加载速度很慢,应用程序滞后)
  • 哈,这改变了一切。您没有提到您有五个以上的项目,因此列表选择器会在不同的页面上打开选择器。好的,这样做的原因是您为简单的项目选择器创建了一个模板(最多五个项目,下拉菜单)。如果列表较长,您还需要创建一个 FullModeItemTemplate。下面是如何创建 FullModeItemTemplate 的示例:windowsphonegeek.com/articles/listpicker-for-wp7-in-depth 然后你应该得到图片和文字!

标签: c# windows-phone-7 xaml


【解决方案1】:

由于您在 ListPicker 中获得了大量项目列表,因此您还需要为其创建一个模板。您目前只有 ItemTemplate。该属性称为 FullModeItemTemplate,此处显示了如何执行此操作的示例:

http://windowsphonegeek.com/articles/listpicker-for-wp7-in-depth

【讨论】:

  • 这绝对有效!尽管我仍然遇到图像未正确填充的相同问题。只有当前选定的背景显示在列表中,所有其他图像都是空白的,然后选择新的后台时,它的图像也会显示出来,但是必须先选择一个项目在图像将与其SHWO上各自的名字。
  • 能否附上截图链接?
  • 我不知道该怎么做,尽管我创建了一个测试项目来仅测试列表选择器,并且它与图像一起工作,除了大约 20 个主题项填充列表选择器之后,我遇到了 OutOfMemoryException。关于如何填充和使用 listpicker 而不会出现此错误,您有什么建议?我已经阅读了有关虚拟化的信息,但我不知道如何做这样的事情?
  • 您还在使用较小的图像(您提到了 50x37.59)吗? 30 张该大小的图像不应导致 OutOfMemoryException
  • 好吧,当我第一次填充列表时,我正在从我的目录中加载图像,它们非常大以适合全景背景,但是当用户查看列表时,图像被调整为 50x37 .59.我可能只需要咬紧牙关,要么不使用列表中的图像,要么只是调整 ListPicker 的所有图像大小,然后使用实际图像大小作为背景。
【解决方案2】:

我最终使用了 FullModeItemTemplate,以便 ListPicker 可以正确填充到另一个页面中。

SettingsPage.xaml

<Grid.Resources>

                        <DataTemplate x:Name="PickerItemTemplate">
                            <StackPanel Orientation="Horizontal">
                                <Image Source="{Binding Image}" Width="50" Height="37.59" Margin="0,0,12,0"/>
                                <TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
                            </StackPanel>
                        </DataTemplate>

                        <DataTemplate x:Name="PickerFullModeItemTemplate">
                            <StackPanel Orientation="Horizontal">
                                <Image Source="{Binding Image}" Width="50" Height="37.59" Margin="0,0,12,0"/>
                                <TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
                            </StackPanel>
                        </DataTemplate>

                    </Grid.Resources>

<toolkit:ListPicker x:Name="ThemeListPicker" Header="Theme" Grid.Row="2" Grid.ColumnSpan="2"
                                        FullModeItemTemplate="{StaticResource PickerFullModeItemTemplate}"
                                        ItemTemplate="{StaticResource PickerItemTemplate}"
                                        SelectedIndex="{Binding}"
                                        SelectionChanged="ThemeListPicker_SelectionChanged"/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多