Reputation: 817
I come from an mobile ios background and so I am not entirely sure if I can use the same strategy for pulling data from a webserver and binding it to UI elements. In ios I can make a web call to one API and connect that data to an element and then do another web call and connect the second set of data to a different element all on the same view in a very easy way. This does not appear to be the case with WPF which is why I feel as though I'm not using the best strategy.
Below is my code. It grabs a list of users from the server and binds to a ListView located on the MainWindow. When a user is selected in the ListView, I want to grab more data on the user by making another call to the server and binding that to a different control also on the MainWindow. This is where I am lost. Should I be switching the DataContext? Should I be doing what the answer in this questions suggests WPF binding multiple controls to different datacontexts ? Or what about keeping all data in the same ObservableCollection? What is the best way to go about this?
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>
Upvotes: 1
Views: 107
Reputation: 110
Coming from the MVVM perspective, in addition to the Users1
property, you should also have a "SelectedUser" property of type UserModel
Then you should bind ListView.SelectedItem
to the SelectedUser
property... obviously, you want to make sure that UserModel
implements INotifyPropertyChanged
and call the PropertyChanged
method within the set of the SelectedUser
property. Also, in the set of the SelectedUser
property, you could make a call to populate the other data that you wanted to have populated on the 'SelectedUser`.
Upvotes: 1
Reputation: 7320
Yes in your example, you can leave the two properties in your ObservableCollection<>, and work directly with them.
In MVVM, in XAML, you can define DataContext via Binding, so you can use multiples ViewModels behind your single View.
I think you should look at the MVVM pattern in first place, and look at some examples. There are lots !!!
Upvotes: 1