簡體   English   中英

在INotifyPropertyChanged上刷新值轉換器

[英]refreshing Value Converter on INotifyPropertyChanged

我知道這里有一些類似的主題,但我無法得到任何答案。 我必須在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
    }

ViewModel:

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


    }

 }

Background="{Binding Converter={StaticResource ImageConverter}}"建議您直接綁定到People (這是刷新時的問題)。

所以,你應該重新安排一下。 將其a property某些其他“更高”數據上下文a property


如何重新安排事情:

1) 您的“模型”(來自db的實體)應該與您的視圖模型不同 為了避免詳細說明,它解決了許多問題 - 例如你所擁有的問題。 People getters / setter通常不以這種方式覆蓋(EF經常使用反射來處理w /實體等)。
因此,讓PeopleVM(對於單人或PersonViewModel ) - 在那里復制東西 - 並在那里制作INotify - 留下人們只是一個純粹的實體/ poco w /自動獲取/設置。

2) PeopleViewModel也是PeopleViewModel - 它與Db過於緊密(這些也是設計指南)。
你不應該重用DbContext - 不要保存它 - 它是一個'一次性'對象(並緩存在里面) - 所以使用using()來按需處理和加載/更新。

3) 用PersonViewModel替換主VM中的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次更改時強制綁定刷新 - 你仍然擁有完整的People(實際上你可以只使用兩個,因為你需要的只有Image和TileColor)。

5)將您的轉換器更改為IMultiValue ...並讀取發送的多個值。

就這樣 :)

簡潔版本:
這是proper way並確定工作(這取決於你如何/何時更新Person屬性等) - 但你可以先嘗試short version - 只需在People模型上做multi-binding部分 - 並希望它能夠工作。 如果不是,你必須做以上所有。

Windows Phone 7:
由於沒有MultiBinding ......
- 使用變通方法 - 它應該非常相似,
- 或者使用上面的(a) - 綁定網格到{Binding ImageAndTileColor, Converter...} 創建新屬性(如果您希望在實體/模型中也可以這樣做 - 只需將其標記為[NotMapped()] ),這將是一個“復合” [NotMapped()]


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

我明白了(感謝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;
            }

    }

然后,每當我像這樣更新Image或TileColor時,我只需要添加調用NotifyPropertyChanged("PeopleId")

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

這會強制值轉換器刷新:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM