1

我知道这里有一些类似的话题,但我无法从他们那里得到任何答案。我必须在我的 Windows Phone 7 应用程序中将网格的背景更新为图像或颜色。我使用我的值转换器执行此操作,它工作正常,但我必须重新加载集合,以便它更新颜色或图像。

<Grid Background="{Binding Converter={StaticResource ImageConverter}}" Width="125" Height="125" Margin="6">

转换器接收对象然后从中获取颜色和图像,这里是转换器

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {

            People myC = value as People;

            string myImage = myC.Image;
            object result = myC.TileColor;

            if (myImage != null)
            {

                BitmapImage bi = new BitmapImage();
                bi.CreateOptions = BitmapCreateOptions.BackgroundCreation;
                ImageBrush imageBrush = new ImageBrush();

                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (myIsolatedStorage.FileExists(myImage))
                    {

                        using (
                            IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(myImage, FileMode.Open,
                                                                                              FileAccess.Read))
                        {
                            bi.SetSource(fileStream);
                            imageBrush.ImageSource = bi;
                        }
                    }
                    else
                    {
                        return result;
                    }
                }

                return imageBrush;
            }
            else
            {
                return result;
            }

    }

我需要以某种方式更新/刷新网格标签或值转换器,以便它可以显示最新的更改!

编辑

添加了更多代码

该模型 :

  [Table]
    public class People : INotifyPropertyChanged, INotifyPropertyChanging
    {


        private int _peopleId;

        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
        public int PeopleId
        {
            get { return _peopleId; }
            set
            {
                if (_peopleId != value)
                {
                    NotifyPropertyChanging("PeopleId");
                    _peopleId = value;
                    NotifyPropertyChanged("PeopleId");
                }
            }
        }

        private string _peopleName;

        [Column]
        public string PeopleName
        {
            get { return _peopleName; }
            set
            {
                if (_peopleName != value)
                {
                    NotifyPropertyChanging("PeopleName");
                    _peopleName = value;
                    NotifyPropertyChanged("PeopleName");
                }
            }
        }




        private string _tileColor;

        [Column]
        public string TileColor
        {
            get { return _tileColor; }
            set
            {
                if (_tileColor != value)
                {
                    NotifyPropertyChanging("TileColor");
                    _tileColor = value;
                    NotifyPropertyChanged("TileColor");
                }
            }
        }



        private string _image;

        [Column]
        public string Image
        {
            get { return _image; }
            set
            {
                if (_image != value)
                {
                    NotifyPropertyChanging("Image");
                    _image = value;
                    NotifyPropertyChanged("Image");
                }
            }
        }


        [Column]
        internal int _groupId;

        private EntityRef<Groups> _group;

        [Association(Storage = "_group", ThisKey = "_groupId", OtherKey = "Id", IsForeignKey = true)]
        public Groups Group
        {
            get { return _group.Entity; }
            set
            {
                NotifyPropertyChanging("Group");
                _group.Entity = value;

                if (value != null)
                {
                    _groupId = value.Id;
                }

                NotifyPropertyChanging("Group");
            }
        }


        [Column(IsVersion = true)]
        private Binary _version;

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region INotifyPropertyChanging Members

        public event PropertyChangingEventHandler PropertyChanging;

        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }

        #endregion
    }

视图模型:

public class PeopleViewModel : INotifyPropertyChanged
{

    private PeopleDataContext PeopleDB;

    // Class constructor, create the data context object.
    public PeopleViewModel(string PeopleDBConnectionString)
    {
        PeopleDB = new PeopleDataContext(PeopleDBConnectionString);
    }


    private ObservableCollection<People> _allPeople;

    public ObservableCollection<People> AllPeople
    {
        get { return _allPeople; }
        set
        {
            _allPeople = value;
            NotifyPropertyChanged("AllPeople");
        }
    }

    public ObservableCollection<People> LoadPeople(int gid)
    {
        var PeopleInDB = from People in PeopleDB.People
                           where People._groupId == gid
                           select People;


        AllPeople = new ObservableCollection<People>(PeopleInDB);

        return AllPeople;
    }


    public void updatePeople(int cid, string cname, string image, string tilecol)
    {
        People getc = PeopleDB.People.Single(c => c.PeopleId == cid);
        getc.PeopleName = cname;
        getc.Image = image;
        getc.TileColor = tilecol;

        PeopleDB.SubmitChanges();

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
    }

    #endregion
}

申请页面

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

        <ListBox Margin="0,8,0,0"  x:Name="Peoplelist" HorizontalAlignment="Center"  BorderThickness="4" ItemsSource="{Binding AllPeople}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Background="{Binding Converter={StaticResource ImageConverter}}" Width="125" Height="125" Margin="6">
                        <TextBlock Name="name" Text="{Binding PeopleName}" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <toolkit:WrapPanel/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

    </Grid>

后面的应用程序页面代码

public partial class PeopleList : PhoneApplicationPage
{

    private int gid;
    private bool firstRun;

    public PeopleList()
    {
        InitializeComponent();
        firstRun = true;
        this.DataContext = App.ViewModel;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {

        gid = int.Parse(NavigationContext.QueryString["Id"]);

        if (firstRun)
        {
            App.ViewModel.LoadPeople(gid);
            firstRun = false;
        }


    }

 }
4

2 回答 2

3

Background="{Binding Converter={StaticResource ImageConverter}}"建议您直接绑定到People 项目(刷新时这是您的问题)。

所以,你应该重新安排一下。改为使用a property其他一些“更高”的数据上下文。


如何重新排列事物:

1)您的“模型”(来自数据库的实体)应该与您的 view-model 不同。为了避免深入细节,它解决了很多问题——比如你遇到的问题。Peoplegetter/setter 通常不会以这种方式被覆盖(EF 经常使用反射来处理实体等)。
因此,制作 PeopleVM(用于单个 People 或PersonViewModel) - 在其中复制内容 - 并在其中制作 INotify - 将 People 保留为带有自动获取/设置的纯实体/poco。

2)同样的PeopleViewModel- 它太依赖于 Db(这些也是设计指南)。
你不应该重用 DbContext - 不要保存它 - 它是一个“一次性”对象(并缓存在里面) - 所以using()用来处理和按需加载/更新。

3)用 PersonViewModel 替换主虚拟机中的 People。当您从 db 加载时,首先将泵送入 PersonVM - 当您以另一种方式保存时。这对于 MVVM 来说是一个棘手的问题,您经常需要复制/复制 - 您可以使用一些工具来自动化或制作复制 ctor-s 或其他东西。
你的ObservableCollection<People> AllPeople变成ObservableCollection<PersonViewModel> AllPeople

4) XAML - 你的绑定 AllPeople, PeopleName 是相同的 - 但现在指向视图模型(和名称到 VM 名称)。
但是你应该把你的东西绑定到(老人)grid以外PersonViewModel的东西上——因为在收藏中很难“刷新”。
a)创建一个新的单个属性,例如ImageAndTileColor- 并确保它在两个属性中的任何一个发生更改时更新/通知。
b)另一种选择是使用MultiBinding- 并绑定 2、3 个属性 - 一个是PersonViewModel你所拥有的整体,再加上其他两个属性 - 例如..

<Grid ...>
    <Grid.Background>
        <MultiBinding Converter="{StaticResource ImageConverter}" Mode="OneWay">
            <MultiBinding.Bindings>
                <Binding Path="Image" />
                <Binding Path="TileColor" />
                <Binding Path="" />
            </MultiBinding.Bindings>
        </MultiBinding>
    </Grid.Background>
    <TextBlock Name="name" Text="{Binding PeopleName}" ... />
</Grid>

这样,当 3 个更改中的任何一个发生更改时,您强制绑定刷新- 并且您仍然拥有完整的人员(实际上您可以只使用两个,因为您只需要 Image 和 TileColor)。

5)将您的转换器更改为 IMultiValue... 并读取发送的多个值。

就这样 :)

简短版本:
这是proper way肯定会起作用的(这取决于您更新 Person 属性的方式/时间等) - 但您可以尝试第short version一个 - 只需multi-binding在 People 模型上做部分 - 并希望它会起作用。如果不是,您必须执行上述所有操作。

Windows Phone 7:
由于没有MultiBinding...
- 使用解决方法- 它应该非常相似,
- 或者使用(a)上面的 - 将网格绑定到{Binding ImageAndTileColor, Converter...}. 创建新属性(如果您希望在实体/模型中执行相同操作 - 只需将其标记为[NotMapped()]),这将是一个“复合”属性。


http://www.thejoyofcode.com/MultiBinding_for_Silverlight_3.aspx

于 2013-04-07T22:32:23.120 回答
0

我明白了(感谢 NSGaga)。我将他的帖子设置为答案,以下是我所做的

首先我需要让转换器接收 PeopleId 而不是对象本身

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {

        int cid = (int)value;
        People myC = App.ViewModel.getPerson(cid);

            string myImage = myC.Image;
            object result = myC.TileColor;

            if (myImage != null)
            {

                BitmapImage bi = new BitmapImage();
                bi.CreateOptions = BitmapCreateOptions.BackgroundCreation;
                ImageBrush imageBrush = new ImageBrush();

                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (myIsolatedStorage.FileExists(myImage))
                    {

                        using (
                            IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(myImage, FileMode.Open,
                                                                                              FileAccess.Read))
                        {
                            bi.SetSource(fileStream);
                            imageBrush.ImageSource = bi;
                        }
                    }
                    else
                    {
                        return result;
                    }
                }

                return imageBrush;
            }
            else
            {
                return result;
            }

    }

NotifyPropertyChanged("PeopleId")然后,每当我像这样更新 Image 或 TileColor 时,我只需要添加调用

    private string _tileColor;

    [Column]
    public string TileColor
    {
        get { return _tileColor; }
        set
        {
            if (_tileColor != value)
            {
                NotifyPropertyChanging("TileColor");
                _tileColor = value;
                NotifyPropertyChanged("TileColor");
                NotifyPropertyChanged("PeopleId");
            }
        }
    }



    private string _image;

    [Column]
    public string Image
    {
        get { return _image; }
        set
        {
            if (_image != value)
            {
                NotifyPropertyChanging("Image");
                _image = value;
                NotifyPropertyChanged("Image");
                NotifyPropertyChanged("PeopleId");
            }
        }
    }

这会强制值转换器刷新:)

于 2013-04-09T01:17:44.303 回答