C#:可能需要网络调用的属性?
我知道在 C# 中,属性应该是快速操作(不是从网络或文件系统等读取数据)。但是,我正在构建一个 Silverlight 应用程序,我需要将 XAML 元素绑定到 ViewModel 上的某些网络数据。据我所知,绑定只能对属性进行,而不能对方法进行。我应该打破这里的准则,还是有其他我没有想到的解决方法?
<ListBox ItemsSource="{Binding Users}" />
public IEnumerable<User> Users
{
get
{
// may be cached
return expensiveNetworkCall();
}
}
I know that in C#, properties are supposed to be quick operations (not reading data from a network or file system, etc.) However, I am building a Silverlight app and I need to bind a XAML element to some network data on a ViewModel. As far as I am aware, binding can only be done to properties, not methods. Should I break the guideline here, or is there another way around this that's not occurring to me?
<ListBox ItemsSource="{Binding Users}" />
public IEnumerable<User> Users
{
get
{
// may be cached
return expensiveNetworkCall();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
实际上,虽然我还没有使用过它,但您可以使用
ObjectDataProvider
绑定到方法。请参阅此处:http://www.thomasclaudiushuber .com/blog/2008/01/10/bind-to-methods-with-objectdataprovider/Actually, although I haven't used it yet, you can bind to methods with the
ObjectDataProvider
. See here: http://www.thomasclaudiushuber.com/blog/2008/01/10/bind-to-methods-with-objectdataprovider/我会违反规则并与财产绑定。虽然,正如 @Tom 所说,您可以绑定到一个方法,但它不会对用户体验产生影响。您可以使用
ObservableCollection
(而不是IEnumerable
)并在另一个线程上加载用户。甚至可能将显式命令绑定到按钮来启动昂贵的呼叫。I would break the rule and bind to the property. Although, as @Tom states, you can bind to a method, it will not make a difference user-experience wise. You could use an
ObservableCollection
(instead ofIEnumerable
) and load the users on another thread. Maybe even with an explicit command bound to a button to initiate the expensive call.我认为这里的问题是 - 你应该让你的用户等待完整的绑定发生吗?您可以将该活动派生到另一个方法并返回您得到的内容(一开始什么也没有,下次调用时返回)。
您还可以让用户知道这些值尚未全部可用,并让他们有机会刷新,然后开始显示长时间运行的网络相关过程的结果。
I think the concern here is - should you make your users wait for the complete binding to take place? You could spawn that activity off to another method and return what you got (nothing in the beginning, something next time they call).
You could also let the users know that the values are not yet all available and give them the chance to refresh and then start showing the results of the long running network related process.
属性只能用于简单的数据/成员访问,并且永远不应该代表网络调用等冗长的操作。有一种方法更适合这种情况。
如今,将其作为一种方法对于您的 UI 场景来说可能很方便,但将来会导致问题。直接绑定到方法不像属性那样容易受支持,因为方法意味着可能不应该绑定到 UI 的操作。例如,如果底层网络连接挂起,将导致 UI 直接挂起。这是一种让用户感到沮丧的快速方法。
这是一种替代方法,
BindingCollection
代替IEnumerable
BindingCollection
开始为空并排队用户的网络请求BindingCollection
(确保调用回 UI 线程)Properties should only be used for simple data / member access and should never represent a lengthy operation such as a network call. A method is much more appropriate for this scenario.
Having it as a method may be convenient today for your UI scenario but will lead to problems down the road. Binding diretly to a method is not supported as easily as properties because a method implies an operation that probably shouldn't be bound to the UI. For example if the underlying network connection hangs it will lead to a direct hang in hte UI. This is a quick way to frustrate users.
Here's an alternative approach
IEnumerable<Users>
use aBindingCollection<Users>
BindingCollection<Users>
start off as empty and queue a network request for the usersBindingCollection<Users>
with the found data (make sure to Invoke back to the UI thread)