[uwp]MVVM模式實戰之必應壁紙查看器


最近學習MVVM,至於什么是MVVM我也在這兒不多說了,一是關於它的解釋解釋網上非常多,二是我怕自己講不清,誤導自己沒關系,誤導別人就不好了。。

好了,廢話結束,看是實戰......

 

這個必應壁紙的demo非常簡單,只有一個頁面,上面有一個Image,一個TextBox和兩個Button控件。

如下圖所示

 

 

 

那么下面吧XAML代碼貼上來

 <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
            <Image Source="{Binding ImageSource}"></Image>
            <TextBox Grid.Row="1" Text="{Binding Copyright}" IsReadOnly="True"></TextBox>
            <Grid HorizontalAlignment="Stretch"  Grid.Row="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Button Content="上一張" Command="{Binding ButtonCommand}" CommandParameter="上一張" HorizontalAlignment="Center" Grid.Column="0"></Button>
                <Button Content="下一張" Command="{Binding ButtonCommand}" CommandParameter="下一張" HorizontalAlignment="Center" Grid.Column="1"></Button>
            </Grid>
        </Grid>
    </Grid>

 

在設計的時候,我是先設計的ViewModel,但是由於設計ViewModel的時候我已經知道必應壁紙的請求參數。

http://cn.bing.com/HPImageArchive.aspx?format=js&idx=idx=0&n=1

有三個查詢參數

  format:這個應該是指定返回數據類型,默認設成js不變

  idx:如果你想獲取昨天的壁紙,那么這個參數就是1,如果是獲取前天的壁紙,那么這個就是2,經過我測試,他的取值范圍是[-1,15],比較有意思的是,-1應該就是明天的壁紙吧,嘿嘿

  n:表示返回數據中包含幾組圖片信息,我設為1

由於我設置的返回格式是json,json的解析我就不貼了,放在demo中,咋們的重點也不是這個。

 

為了在下面的ViewModel中不出現混亂,我先給出Model的定義。

namespace 必應壁紙實戰.Model
{
    public class BingImageModel
    {public string copyright { get; set; }//返回圖片的copyright
        public Uri uri { get; set; }         //返回具體圖片的uri
        public int idx { get; set; } = 0;
        public int n { get; set; } = 1;
    }
}

 

ViewModel的設計是我結合了View中的需求設計的。

namespace 必應壁紙實戰.ViewModle
{
    public class BingImageViewModel: ViewModelBase
    {
        private string _copyright;
        public string Copyright
        {
            get
            {
                return _copyright;
            }

            set
            {
                _copyright = value;
                OnPropertyChanged();
            }
        }

        private BitmapImage _imageSource;
        public BitmapImage ImageSource
        {
            get
            {
                return _imageSource;
            }

            set
            {
                _imageSource = value;
                OnPropertyChanged();
            }
        }
        
        private int index;
        public int Index
        {
            get
            {
                return index;
            }

            set
            {
                if (value <= 0)
                    value = 0;
                index = value;
                IndexChanged();
            }
        }

        public RelayCommand ButtonCommand { get; set; }

        public BingImageModel Model { get; set; }

        private void ButtonDown(object param)
        {
            string tag = param as string;
            if (tag != null)
            {
                if (tag == "上一張")
                {
                    Index++;
                }
                else
                {
                    Index--;
                }
            }
        }

        public BingImageViewModel()
        {
            Model = new BingImageModel();

            ButtonCommand = new RelayCommand();
            ButtonCommand.ExcuteParam = ButtonDown;

            Index = 0;
            Copyright = "";
        }

        private async void IndexChanged()
        {
            Model = await HttpService.GetBingImageModel(Index);
            if (Model != null)
            {
                ImageSource = await HttpService.GetBingImage(Model);
                Copyright = Model.copyright;
            }
        }
    }
}
ViewModel

我對ViewModel做一個簡單說明

ImageSource和Image空間的Source屬性綁定

Copyright和TextBox的Text屬性綁定

ButtonCommand和兩個Button的Command屬性綁定,並且通過CommandParameter來區別執行的命令

Index對應請求參數idx,在它的值改變后執行IndexChanged來獲取必應壁紙

ButtonDown方法對應ButtonCommand來實現對Index的修改,自增代表前一天,自減代表后一天

Model封裝了獲取壁紙的一些必要信息,結合Service中定義的HttpClinet的helper來實現具體的網絡數據請求。

此外,作為WVVM的必備模式,ViewModel是繼承自ViewModelBase的,用以實現綁定機制。

 

完成View,ViewModel,和Model后,一定不要忘記在View中對ViewModel的綁定,最簡單就是類似於“this.DataContext=new ViewModel();”了

 

到這兒就基本完成了,但感覺寫的有些混亂,我把整個過程中的幾個坑在這兒說說

1.就是關於WVVM,一直沒有弄明白在ViewModel中寫大量的代碼究竟好不好,我還有待研究;

2.用Windows.Web.Http命名空間定義的HttpClient請求圖片數據后,用如下方式實現對一個BitmapImage對象的設置

  

            BitmapImage bitMap = new BitmapImage(); ;
            var response=await HttpClient.GetAsync(model.uri);
            var buffer = await response.Content.ReadAsBufferAsync();

            byte[] bytes = new byte[buffer.Length];
            buffer.CopyTo(bytes); //CopyTo是一個定義在System.Runtime.InteropServices.WindowsRuntime;的對IBuffer的拓展方法,這個一定注意
            using (MemoryStream memoryStream = new MemoryStream(bytes))
            {
                var randomstream = memoryStream.AsRandomAccessStream();
                await bitMap.SetSourceAsync(randomstream);
            }        

 

 

好了,上demo代碼,點擊“我是代碼”下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM