【问题标题】:Setting XAML Data Bindings programmatically in C# on application start在应用程序启动时以编程方式在 C# 中设置 XAML 数据绑定
【发布时间】:2012-09-11 12:04:27
【问题描述】:

目前我有一个简单的 Twitter 客户端,上面有一个刷新按钮,该按钮链接到一个通过列表绑定刷新时间线的命令。目前我正在通过以下方式实现这一目标:

XAML:

<Grid x:Name="TimelineGrid">
        <Button Content="Refresh Timeline" Name="RefreshTimeline" Command="{Binding RefreshCommand}" />
        <ListView Name="SearchListBox" ItemsSource="{Binding Tweets}" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" Height="132">
                        <Image Source="{Binding ImageUrl}" 
                           Height="73" Width="73" 
                           VerticalAlignment="Top" Margin="5,10,8,0"/>
                        <StackPanel Width="auto">
                            <TextBlock Text="{Binding Name}" 
                                   Foreground="#222" FontSize="28" />
                            <TextBlock Text="{Binding Text}" 
                                    Foreground="#555" TextWrapping="Wrap" FontSize="24" />
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
</Grid>

ViewModel.cs:

class ViewModel : INotifyPropertyChanged
{
    public List<Tweet> Tweets { get; set; }

    readonly Page page;

    public ViewModel(Page page)
    {
        this.page = page;
        RefreshCommand = new TwitterCommand<object>(OnRefresh);
    }

    public TwitterCommand<object> RefreshCommand { get; set; }

    void OnRefresh(object obj)
    {
        PinAuthorizer auth =
        new PinAuthorizer
        {
            Credentials = new LocalDataCredentials()
        };

        if (auth == null || !auth.IsAuthorized)
        {
            page.Frame.Navigate(typeof(oAuth));
            return;
        }

        var twitterCtx = new TwitterContext(auth);

        var timelineResponse =
            (from tweet in twitterCtx.Status
             where tweet.Type == StatusType.Home && tweet.Count == 200
             select tweet)
            .ToList();

        Tweets =
            (from tweet in timelineResponse
             select new Tweet
             {
                 Name = tweet.User.Name,
                 Text = tweet.Text,
                 ImageUrl = tweet.User.ProfileImageUrl
             })
            .ToList();

        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Tweets"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public List<User> Users { get; set; }

}

现在我想在加载 MainPage.xaml.cs 时填充此时间线。

目前我有 MainPage.xaml.cs:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        DataContext = new ViewModel(this);
        InitializeTimeline();
    }


    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

    void InitializeTimeline()
    {
        // Get oAuth tokens (They already exist for this example).
        PinAuthorizer auth =
        new PinAuthorizer
        {
            Credentials = new LocalDataCredentials()
        };

        var twitterCtx = new TwitterContext(auth);

        //create list timelineResponse populated of last 200 statuses from users home timeline.

        var timelineResponse =
            (from tweet in twitterCtx.Status
             where tweet.Type == StatusType.Home && tweet.Count == 200
             select tweet)
            .ToList();

        //new list of Tweet (contains strings for Name, Text and ImageUrl)
        List<Tweet> Tweets = new List<Tweet>();

        //Populate list with the data collected from timeline response
        Tweets =
            (from tweet in timelineResponse
             select new Tweet
             {
                 Name = tweet.User.Name,
                 Text = tweet.Text,
                 ImageUrl = tweet.User.ProfileImageUrl
             })
            .ToList();
    }
}

现在我在想最好的解决方法是遍历这个 List 并将值分配给 MainPage.xaml 中它们各自的列表值,但目前我正在努力解决这个问题。

非常感谢任何帮助:)

【问题讨论】:

    标签: c# xaml listview data-binding


    【解决方案1】:

    如果我理解正确,您只需要在加载主页时显示推文 - 而不仅仅是在单击刷新按钮时。

    为此,只需从 MainViewModel 手动调用 ViewModel RefreshCommand,如下所示:

    ((ViewModel)DataContext).RefreshCommand.Execute(null);
    

    这代替了InitializeTimeline 调用。

    然后刷新命令将加载推文并更新列表 - 无论如何它都绑定到 ListView。

    然后您可以摆脱 InitializeTimeline。

    【讨论】:

    • 现在,如果您使用 IoC 容器,您可以在没有任何代码隐藏的情况下执行此操作 - 但您拥有的分离级别通常就足够了 - 只要您没有太多代码隐藏.追求纯粹的 MVVM 解决方案有时是不值得的 :)
    猜你喜欢
    • 2014-09-26
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多