0

我有一个 ListPicker,它有几个不同的颜色值选项。选择颜色值后,我想立即在视图中的某些项目上显示该颜色。不过,我对如何最好地做到这一点有点困惑。

编辑页面.xaml

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Name="ListPickerItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding Image}" Width="50" Height="37.59"/>
            <TextBlock Text="{Binding Name}" Foreground="{Binding Brush}" Margin="12,0,0,0" TextWrapping="Wrap"/>
        </StackPanel>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

...

<toolkit:ListPicker x:Name="themeListPicker" Header="Theme" FullModeHeader="Theme" CacheMode="BitmapCache"
                                        SelectionChanged="themeListPicker_SelectionChanged"
                                        ItemTemplate="{StaticResource ListPickerItemTemplate}" 
                                        FullModeItemTemplate="{StaticResource ListPickerFullModeItemTemplate}"/>

编辑页面.xaml.cs

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

        themeList = new List<Theme>();
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Indigo.png", UriKind.Relative)), Name = "indigo", Color = Color.FromArgb(255, 106, 0, 255) });
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cyan.png", UriKind.Relative)), Name = "cyan", Color = Color.FromArgb(255, 27, 161, 226) });
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cobalt.png", UriKind.Relative)), Name = "cobalt", Color = Color.FromArgb(255, 0, 80, 239) });

        themeListPicker.ItemsSource = themeList;
    }

private void themeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (themeListPicker.SelectedItem == null)
            return;

        CurrentTheme = themeListPicker.SelectedItem as Theme;
    }

public class Theme : NotifyingObject
{
    public BitmapImage Image { get; set; }
    public string Name { get; set; }
    public Color Color { get; set; }
    public SolidColorBrush Brush
    {
        get
        {
            return new SolidColorBrush(Color);
        }
    }

    private Theme _currentTheme;
    public Theme CurrentTheme
    {
        get
        {
            return _currentTheme;
        }

        set
        {
            if (value == _currentTheme) return;
            _currentTheme = value;
            NotifyPropertyChanged("CurrentTheme");
        }
    }
}

我不确定我是否正确地将这些放在一起。另外,如何立即将当前选择的颜色显示为视图中对象的颜色或对象的某些属性?我有几个 ToggleSwitches、一个 Slider bar 等,在 ListPicker 中选择一个新项目后应该立即改变颜色。

编辑**

编辑页面.xaml

<phone:PhoneApplicationPage.Resources>       
    <DataTemplate x:Name="ListPickerItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding CurrentTheme.Image}" Width="50" Height="37.59"/>
            <TextBlock Text="{Binding CurrentTheme.Name}" Foreground="{Binding CurrentTheme.Brush}" Margin="12,0,0,0" TextWrapping="Wrap"/>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Name="ListPickerFullModeItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding CurrentTheme.Image}" Width="50" Height="37.59"/>
            <TextBlock Text="{Binding CurrentTheme.Name}" Foreground="{Binding CurrentTheme.Brush}" Margin="12,0,0,0" TextWrapping="Wrap"/>
        </StackPanel>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

..

<toolkit:ListPicker x:Name="themeListPicker" Header="Theme" FullModeHeader="Theme" 
                                        ItemsSource="{Binding Themes}" CacheMode="BitmapCache"
                                        SelectionChanged="themeListPicker_SelectionChanged"
                                        ItemTemplate="{StaticResource ListPickerItemTemplate}" 
                                        FullModeItemTemplate="{StaticResource ListPickerFullModeItemTemplate}"/>

<Slider x:Name="Slider"  Minimum="1" Maximum="6" Margin="12,20,12,0" Foreground="{Binding CurrentTheme.Brush}"
                    ValueChanged="Slider_ValueChanged" Value="1"/>

编辑页面.xaml.cs

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

        themeList = new List<Theme>();
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Indigo.png", UriKind.Relative)), Name = "indigo", Color = Color.FromArgb(255, 106, 0, 255) });
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cyan.png", UriKind.Relative)), Name = "cyan", Color = Color.FromArgb(255, 27, 161, 226) });
        themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cobalt.png", UriKind.Relative)), Name = "cobalt", Color = Color.FromArgb(255, 0, 80, 239) });

        var viewModel = new ThemeViewModel();
        viewModel.Themes = themeList;
        DataContext = viewModel;
    }

private void themeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //var theme = (sender as ListPicker);
        //MessageBox.Show("Chosen theme: " + e.AddedItems[0].ToString());

        if (themeListPicker.SelectedItem == null)
            return;

        //How to save the current theme color in IsoStore?
        var CurrentTheme = themeListPicker.SelectedItem as Theme;
        //Custom Settings class to save current color in IsoStore
        Settings.themeBrush.Value = CurrentTheme.Brush;
    }

ThemeViewModel.cs

private Theme _currentTheme;        
    public Theme CurrentTheme
    {
        get { return _currentTheme; }
        set
        {
            if (value == _currentTheme) return;
            _currentTheme = value;
            NotifyPropertyChanged("CurrentTheme");
        }
    }

    private IList<Theme> _themes;
    public IList<Theme> Themes
    {
        get { return _themes; }
        set
        {
            if (value == _themes) return;
            _themes = value;
            NotifyPropertyChanged("Themes");
        }
    }

主题.cs

public BitmapImage Image { get; set; }
    public string Name { get; set; }
    public Color Color { get; set; }
    public SolidColorBrush Brush
    {
        get
        {
            return new SolidColorBrush(Color);
        }
    }

设置.cs

//Theme
    public static readonly Setting<SolidColorBrush> themeBrush = new Setting<SolidColorBrush>("themeBrush", new SolidColorBrush(Color.FromArgb(255, 106, 0, 255)));

CurrentTheme使用绑定中的这种新编辑和设置,例如Foreground="{Binding CurrentTheme.Brush}"ListPicker 中的项目是不可见的,但是当我CurrentTheme从绑定中删除时,例如Foreground="{Binding Brush}"ListPicker 中的项目显示与它们相关的颜色?沿着这些CurrentTheme思路,在控件的前景绑定中使用或不使用都不起作用Slider,因此前景似乎只是透明的。另外,当进行新的 ListPicker 选择时,如何以这种方式更改 ListPicker 的边框?另外,我需要保存当前的主题颜色,以便视图中的项目在返回应用程序时具有相同的颜色。在 ListPicker 中选择新项目后,为项目分配永久颜色的最佳方法是什么?我有一个Settings上面显示的类,它可以将画笔值存储在 IsoStore 中,但是如何按照您的解决方案将其应用于视图中的项目(通常我会在后面的代码中显式执行此操作)?

4

2 回答 2

1

如果您采用如下的 MVVM 方法,我认为您会发现这要容易得多。

创建一个 PageViewModel 来表示您的所有数据。例如:

public class PageViewModel : NotifyingObject
{
    public Theme CurrentTheme
    {
        get { return _currentTheme; }
        set
        {
            if (value == _currentTheme) return;
            _currentTheme = value;
            NotifyPropertyChanged("CurrentTheme");
        }
    }
    public IList<Theme> Themes
    {
        get { return _themes; }
        set
        {
            if (value == _themes) return;
            _themes = value;
            NotifyPropertyChanged("Themes");
        }
    }
}

现在为您的 DataContext 分配一个新的 PageViewModel:

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

    themeList = new List<Theme>();
    themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Indigo.png", UriKind.Relative)), Name = "indigo", Color = Color.FromArgb(255, 106, 0, 255) });
    themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cyan.png", UriKind.Relative)), Name = "cyan", Color = Color.FromArgb(255, 27, 161, 226) });
    themeList.Add(new Theme() { Image = new BitmapImage(new Uri("/Assets/Themes/Cobalt.png", UriKind.Relative)), Name = "cobalt", Color = Color.FromArgb(255, 0, 80, 239) });

    var viewModel = new PageViewModel();
    viewModel.Themes = themeList;
    DataContext = viewModel;
}

现在在您的 xaml 中将您的列表选择器绑定到您的视图模型:

<toolkit:ListPicker ... ItemsSource="{Binding Themes}" .../>

现在您可以绑定您想要的任何其他元素,例如:

<TextBlock Text="{Binding CurrentTheme.Name}" Foreground="{Binding CurrentTheme.Brush}">

编辑:

通过将此绑定添加到 ListPicker,确保您的 CurrentTheme 正在更新:

<toolkit:ListPicker ... SelectedItem="{Binding CurrentTheme, Mode=TwoWay}" >

正如您所发现的,您DataTemplate的 s 不应该CurrentTheme在它们的绑定中。DataTemplates 中的绑定应该与 ListPicker 中的单个项目相关(即 a 上的任何内容Theme

于 2013-11-12T05:13:57.267 回答
1

如果我正确理解你,你不能简单地在EventForeground的视图中设置 UI 元素吗?SelectionChanged它将立即反映更改。

private void themeListPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (themeListPicker.SelectedItem == null)
        return;

    CurrentTheme = themeListPicker.SelectedItem as Theme;
    SolidColorBrush b = CurrentTheme.Brush;
    //Change foreground of toggle switch, slider etc you want here
    toggle.Foreground = b;
    slider.Foreground = b;
}

如果您要更改的 UI 元素与ListPickerthen绑定MVVM是最好的方法。尽管您必须将DataContext整个容器的属性设置为您的类,并且这将在访问 UI 元素属性时引入某些依赖项。您将不得不将您需要的所有内容绑定到Theme班级,例如。TextBlock的文本、前景等。如果这样做,请确保所有内容都已INotifyPropertyChanged继承以反映任何动态更改。

于 2013-11-12T07:12:05.327 回答