【问题标题】:Strategy for binding different pieces of data to different controls in the same window将不同数据块绑定到同一窗口中不同控件的策略
【发布时间】:2015-01-29 21:17:31
【问题描述】:

我来自移动 ios 背景,因此我不完全确定是否可以使用相同的策略从网络服务器中提取数据并将其绑定到 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>

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    在您的示例中是的,您可以将这两个属性留在 ObservableCollection 中,并直接使用它们。

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

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

    【讨论】:

    • 您可以但通常不应该在同一个视图中拥有多个DataContext。当你这样做时,它会真的感到困惑。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 2011-06-30
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多