使用WPF MVVM而不使用后台代码来呈现UserControl列表的正确方法是什么?

时间:2019-01-25 14:43:51

标签: c# wpf mvvm user-controls observablecollection

我正在尝试创建WPF MVVM程序,客户端将在该程序中从服务器下载文件列表,向用户显示文件并允许他们下载这些文件。

我已经开发了服务器,但是正在为该列表的显示而苦苦挣扎。

我已经拥有:创建BaseViewModel,创建RelayCommand,创建MainViewModel,创建DownloadViewModel,其中包含RemoteDiscElementViewModels的ObservableCollection,它是服务器中单个文件的ViewModel,创建的RemoteDiscElementView,创建的DownloadView

ObservableCollection正确加载,但是当我将集合绑定到ItemsControl时,适当数量的RemoteDiscElementViews呈现器,但是它们都是空的。

DownloadViewModel:

public class DownloadViewModel : BaseViewModel
{
    public Client Client { get; set; }
    public ObservableCollection<RemoteDiscElementViewModel> RemoteDiscElementViewModels { get; set; }
    public static DownloadViewModel Download1;
    void Awake()
    {
        Download1 = this;
    }
    public DownloadViewModel()
    {
        Client = new Client();
        RemoteDiscElementViewModels = new ObservableCollection<RemoteDiscElementViewModel>();
    }
    public DownloadViewModel(string address, int port)
    {
        Client = new Client(address, port);
        RemoteDiscElementViewModels = new ObservableCollection<RemoteDiscElementViewModel>();
        Client.Connect();
        GetFiles();
    }

    public void GetFiles()
    {
        RemoteDiscElementViewModels.Clear();
        var content = Client.ListFiles();
        foreach(var file in content)
        {
            RemoteDiscElementViewModel newFile = new RemoteDiscElementViewModel(file.Type, file.Filename, file.Filepath, file.Fileext, file.Filesize);
            RemoteDiscElementViewModels.Add(newFile);
        }
    }



}

RemoteDiscElementViewModel:

public class RemoteDiscElementViewModel : BaseViewModel
{
    private string type;
    private string filename;
    private string filepath;
    private int filesize;
    private string fileext;
    private bool isDownloaded;

    public RemoteDiscElementViewModel()
    {

    }
    public RemoteDiscElementViewModel(string type, string filename, string filepath, string fileext, int filesize)
    {
        Type = type;
        Filename = filename;
        Filepath = filepath;
        Fileext = fileext;
        Filesize = filesize;
        IsDownloaded = false;

    }

    public void Download()
    {
        DownloadViewModel.Download1.Client.SendFile(Filename);
    }
}

RemoteDiscElementView:

 <UserControl x:Class="sikFtpClient.View.RemoteDiscElementView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:sikFtpClient.View"
         xmlns:vm="clr-namespace:sikFtpClient.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
    <vm:RemoteDiscElementViewModel/>
</UserControl.DataContext>
<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Content="{Binding Filename}" Grid.Column="0"/>
        <Button Command="{Binding DownloadCommand}" Grid.Column="1"/>
    </Grid>
</Grid>

在不使用代码隐藏的情况下显示UserControl的ObservableCollection的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

DownloadView可以这样编写,例如:

<UserControl...>
    <ListBox ItemsSource="{Binding Path=(local:DownloadViewModel.RemoteDiscElementViewModels), Mode=OneWay}">
        <ListBox.ItemTemplate>
            <DataTemplate DataType="{x:Type local:RemoteDiscElementViewModel}">
                <local:RemoteDiscElementView/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</UserControl>

在“ RemoteDiscElementView”中,您也不需要以下代码:

<UserControl.DataContext>
    <vm:RemoteDiscElementViewModel/>
</UserControl.DataContext>

因为DataContext是由ListBox的子级隐式设置的。

最后,确保“ DownloadView”的DataContext设置为DownloadViewModel对象。

编辑:

在“ RemoteDiscElementViewModel”中添加了以下属性:

public String Type => _type;
public String Filename => _filename;
public String Filepath => _filepath;
public Int32 Filesize => _filesize;
public String Fileext => _fileext;
public Boolean IsDownloaded => _isDownloaded;

Client.ListFiles()函数使用的伪数据:

public List<RemoteDiscElementViewModel> ListFiles() {
    return Enumerable.Range(0, 20).Select(i => new RemoteDiscElementViewModel("type", "file", "filepath", "fileext", 5)).ToList();
}

并使用地址和端口使用“ DownloadViewModel”的构造函数,它显示了一些内容:

Test