在同一窗口中将不同数据绑定到不同控件的策略

时间:2015-01-29 21:17:32

标签: c# wpf data-binding

我来自移动ios背景,所以我不完全确定我是否可以使用相同的策略从Web服务器提取数据并将其绑定到UI元素。在ios中,我可以对一个API进行Web调用,并将该数据连接到一个元素,然后进行另一个Web调用,并以非常简单的方式将第二组数据连接到同一视图上的不同元素。这似乎不是WPF的情况,这就是为什么我觉得我没有使用最佳策略。

以下是我的代码。它从服务器获取用户列表并绑定到MainWindow上的ListView。当在ListView中选择用户时,我想通过再次调用服务器并将其绑定到MainWindow上的其他控件来获取有关用户的更多数据。这是我迷失的地方。我应该切换DataContext吗?我应该做这个问题的答案建议WPF binding multiple controls to different datacontexts吗?或者将所有数据保存在同一个ObservableCollection中呢?最好的方法是什么?

MainWindow.xaml.cs

public partial class MainWindow
{

    public MainWindow()
    {

        InitializeComponent();
        this.DataContext = new GrabUserModel();

    }
    private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

        Type t = ListView1.SelectedItem.GetType();
        System.Reflection.PropertyInfo[] props = t.GetProperties();
        string propertyValue = props[0].GetValue(ListView1.SelectedItem, null).ToString();
        //Get more info about selected user

    }

}

GrabUserModel.cs

public class GrabUserModel
{
       public static ObservableCollection<UserModel> _Users1 = new ObservableCollection<UserModel>();

    public ObservableCollection<UserModel> Users1
    {
        get { return _Users1; }
        set { _Users1 = value; }
    }


    public GrabUserModel()
    {
                  RunClient();
    }
    private static string _address = "http://somewebsite.com/test.php";

    private static async void RunClient()
    {

        ObservableCollection<UserModel> Users1 = new ObservableCollection<UserModel>();

        HttpClient client = new HttpClient();

        var formContent = new FormUrlEncodedContent(new[]
     {
     new KeyValuePair<string, string>("user_id", "1")
     });
        HttpResponseMessage response = await client.PostAsync(_address, formContent);
        var jsonString = await response.Content.ReadAsStringAsync();

        response.EnsureSuccessStatusCode();

        JObject results = JObject.Parse(jsonString);
        foreach (var result in results["Result"])
        {
            int user_id = (int)result["user_id"];
            string username = (string)result["username"];
           _Users1.Add(new UserModel { user_id = user_id, username = username });
        }
    }
}

MainWindow.xaml

<ListView x:Name="ListView1" HorizontalAlignment="Left" Width="208" ItemsSource='{Binding Users1}' Background="#FF4B4848" BorderBrush="{x:Null}" Margin="0,0,0,0" SelectionChanged="ListView1_SelectionChanged">
    <ListView.ItemTemplate>  
        <DataTemplate>
            <Grid Height="50" Margin="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Label Grid.Row="0" Grid.Column="0" Content="{Binding user_id}" />
                <Label Grid.Row="0" Grid.Column="1" Content="{Binding username}" />
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

2 个答案:

答案 0 :(得分:1)

在您的示例中,您可以将两个属性保留在ObservableCollection&lt;&gt;中,并直接使用它们。

在MVVM中,在XAML中,您可以通过Binding定义DataContext,因此您可以在单个View后面使用多个ViewModel。

我认为您应该首先查看MVVM模式,并查看一些示例。有很多!!!

答案 1 :(得分:1)

从MVVM的角度来看,除了Users1属性之外,你还应该有一个&#34; SelectedUser&#34;类型为UserModel的属性然后您应该将ListView.SelectedItem绑定到SelectedUser属性...显然,您要确保UserModel实现INotifyPropertyChanged并调用PropertyChanged属性集合中的SelectedUser方法。此外,在SelectedUser属性的集合中,您可以调用以填充您想要在&#39; SelectedUser`上填充的其他数据。