C# 如何在视图中立即更改项目的颜色

C# 如何在视图中立即更改项目的颜色,c#,windows-phone-7,windows-phone-8,C#,Windows Phone 7,Windows Phone 8,我有一个ListPicker,它有几个不同的颜色值选项。选择颜色值后,我希望立即在视图中的某些项目上显示该颜色。我有点困惑如何最好地完成这一点 EditPage.xaml <phone:PhoneApplicationPage.Resources> <DataTemplate x:Name="ListPickerItemTemplate"> <StackPanel Orientation="Horizontal">

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

EditPage.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}"/>
<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"/>
设置.cs

//Theme
    public static readonly Setting<SolidColorBrush> themeBrush = new Setting<SolidColorBrush>("themeBrush", new SolidColorBrush(Color.FromArgb(255, 106, 0, 255)));
//主题
公共静态只读设置themeBrush=new设置(“themeBrush”,新的SolidColorBrush(Color.FromArgb(255,106,0,255));

有了这个新的编辑和设置,绑定中的
CurrentTheme
,比如
Foreground=“{binding CurrentTheme.Brush}”
列表选择器中的项目是不可见的,但是当我从绑定中移除
CurrentTheme
时,比如在
Foreground=“{binding Brush}”
ListPicker项是否显示其关联的颜色?沿着这些思路,在
滑块
控件的前台绑定中使用或不使用
CurrentTheme
都不起作用,因此前台似乎是透明的。另外,在选择新的ListPicker时,如何以这种方式更改ListPicker的边框?此外,我需要保存当前的主题颜色,以便视图中的项目在返回应用程序时具有相同的颜色。在ListPicker中选择新项目后,为项目分配永久颜色的最佳方法是什么?我有一个上面显示的
Settings
类,它可以在IsoStore中存储画笔值,但是我如何将它应用到您的解决方案后视图中的项目(通常我会在代码隐藏中显式地这样做)?

我想如果您采用如下MVVM方法,您会发现这会容易得多

创建一个PageViewModel来表示所有数据。e、 g:

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");
        }
    }
}
公共类页面视图模型:NotifyingObject
{
公共主题
{
获取{return\u currentTheme;}
设置
{
if(value==\u currentTheme)返回;
_当前主题=值;
NotifyPropertyChanged(“当前主题”);
}
}
公共主题
{
获取{return\u themes;}
设置
{
如果(值==_)返回;
_主题=价值;
NotifyPropertyChanged(“主题”);
}
}
}
现在将新的PageViewModel分配给DataContext:

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;
}
受保护的覆盖无效OnNavigatedTo(NavigationEventArgs e)
{
基地。导航到(e);
themeList=新列表();
添加(new-Theme(){Image=new-BitmapImage(new-Uri(“/Assets/Themes/Indigo.png”,UriKind.Relative)),Name=“Indigo”,Color=Color.FromArgb(255,106,0,255)});
添加(new-Theme(){Image=new-BitmapImage(new-Uri(“/Assets/Themes/Cyan.png”,UriKind.Relative)),Name=“Cyan”,Color=Color.FromArgb(255,27,161,226)});
添加(new-Theme(){Image=new-BitmapImage(new-Uri(“/Assets/Themes/Cobalt.png”,UriKind.Relative)),Name=“Cobalt”,Color=Color.FromArgb(255,0,80239)});
var viewModel=new PageViewModel();
viewModel.Themes=主题列表;
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中的单个项相关(即
主题上的任何内容)

如果我正确理解您的意思,您不能简单地在
SelectionChanged
事件中设置视图中UI元素的
前台
?它将立即反映这些变化

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元素与
ListPicker
绑定,那么
MVVM
是最好的方法。尽管您必须将整个容器的
DataContext
设置为您的类,这将引入对访问UI元素属性的某些依赖。您必须将所需的所有内容绑定到
主题
类,例如
文本块
的文本,前台等。如果执行此操作,请确保所有控件都继承了
INOTIFYPROPERTYCHANGE
以反映任何动态更改。

要更改控件的颜色,可以将
笔刷
绑定到该控件的
前台
属性,以实现简单控件。对于更复杂的控件,如
列表选择器
,您必须创建一个
控件模板
,正如我在另一个答案()中所建议的那样,您可能希望对其进行投票或选择作为答案,因为您在这个问题中使用了我的代码…:)事实上,你应该把MVVM看作是“IIAN建议”。哦,是的,我忘了投票!现在就可以了!谢谢。我按照你的建议考虑使用MVVM,并更新了上面的解决方案。但是,我确实有一个问题:如何从ListPicker保存所选颜色,并将其永久(立即)应用于视图中的项目。另外,我在
App.xaml
中有一个样式,其中属性采用颜色值,我如何应用该颜色?我尝试了您的解决方案,它确实有效,尽管我想使用MVVM方法,但它似乎更具动态性。我在上面编辑了我的解决方案,底部有几个问题。也许你可以提供一些见解?(当涉及到将类的项绑定到视图时,我对MVVM有些陌生)。好的,我已经相应地更新了我的解决方案,尽管我仍然有一些问题。我在上面添加了一个编辑以反映我的更改。您能否根据上述解决方案深入了解我的问题?您似乎没有更新ViewModel上的CurrentTheme。我将对上面的内容进行编辑。确定,这起到了作用,我还删除了
SelectionChanged
事件。我想我想知道的是如何永久保存
<toolkit:ListPicker ... ItemsSource="{Binding Themes}" .../>
<TextBlock Text="{Binding CurrentTheme.Name}" Foreground="{Binding CurrentTheme.Brush}">
<toolkit:ListPicker ... SelectedItem="{Binding CurrentTheme, Mode=TwoWay}" >
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;
}