2014-08-31 15 views
6

Tôi muốn biết cách được đề xuất để liên kết với ReactiveCommand's IsExecuting.Ràng buộc để ReactiveCommand.IsExecuting

Vấn đề là việc thực hiện lệnh ban đầu (bắt đầu ở cuối hàm tạo) không cập nhật điều khiển WPF bằng cách sử dụng IsLoading làm ràng buộc, mặc dù các cuộc gọi tiếp theo hoạt động như mong đợi.

Cập nhật 2 Add kiểm tra ràng buộc đang

Điều này cho thấy nội dung adorner khi IsLoading là đúng

<ac:AdornedControl IsAdornerVisible="{Binding IsLoading}"> 
    <ac:AdornedControl.AdornerContent> 
     <controls1:LoadingAdornerContent/> 
    </ac:AdornedControl.AdornerContent> 
    <fluent:ComboBox 
     ItemsSource="{Binding Content, Mode=OneWay}" 
     DisplayMemberPath="Name" 
     SelectedValuePath="ContentId" 
     SelectedValue="{Binding SelectedContentId}" 
     IsSynchronizedWithCurrentItem="True" 
    /> 
</ac:AdornedControl> 

Cập nhật

Tôi thấy điều này: https://github.com/reactiveui/rxui-design-guidelines

và figured tôi sẽ có thể làm điều gì đó như:

this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting) 
    .ToProperty(this, x => x.IsLoading); 

nhưng nó mang lại những lỗi biên dịch:

The type arguments for method 'ReactiveUI.OAPHCreationHelperMixin.ToProperty< TObj,TRet>(System.IObservable< TRet>, TObj, System.Linq.Expressions.Expression< System.Func< TObj,TRet>>, TRet, System.Reactive.Concurrency.IScheduler)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Tôi cũng đã cố gắng:

this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting) 
    .ToProperty<TheViewModel, bool>(this, x => x.IsLoading); 

nhưng nhận được lỗi biên dịch:

'System.IObservable< System.IObservable< bool >>' does not contain a definition for 'ToProperty' and the best extension method overload 'ReactiveUI.OAPHCreationHelperMixin.ToProperty< TObj,TRet>(System.IObservable< TRet>, TObj, System.Linq.Expressions.Expression< System.Func< TObj,TRet>>, TRet, System.Reactive.Concurrency.IScheduler)' has some invalid arguments

Instance argument: cannot convert from 'System.IObservable>' to 'System.IObservable'

gốc Dưới

Các mã được liệt kê ở phần cuối của bài tác phẩm của tôi cho ràng buộc ban đầu bằng cách truy cập IsLoading tài sản và nó có vẻ như khởi động một thuê bao. Nhưng từ việc đọc thêm có vẻ như tôi nên sử dụng WhenAny và tôi dường như không thể tìm ra những gì đã được đưa trước mũi tôi:

ToProperty and BindTo - Get initial value without Subscribing

Thêm:

this.WhenAnyValue(x => x.LoadCommand.IsExecuting); 

cũng làm việc , nhưng có cách nào tốt hơn không?

Tôi đã suy nghĩ tháo ObservableAsPropertyHelper vì nó dường như không thể làm nhiều cho tôi và làm cho IsLoading một tài sản thông thường như:

private bool _isLoading; 

public bool IsLoading 
{ 
    get { return _isLoading; } 
    set { this.RaiseAndSetIfChanged(ref _isLoading, value); } 
} 

Và làm một cái gì đó như sau, nhưng nó không biên dịch bởi vì nó đang cố gắng gán một IObservable< bool> đến một bool:

this.WhenAnyValue(x => x.LoadCommand.IsExecuting) 
    .Subscribe(x => IsLoading = x); 

đang hiện tại:

private readonly ObservableAsPropertyHelper<bool> _isLoading; 

public bool IsLoading 
{ 
    get { return _isLoading.Value; } 
} 

LoadCommand = ReactiveCommand.CreateAsyncTask(async _ => 
{ 
    //go do command stuff like fetch data from a database 
} 

LoadCommand.IsExecuting.ToProperty(this, x => x.IsLoading, out _isLoading); 

//works if I have this line 
var startSubscription = IsLoading; 

LoadCommand.ExecuteAsyncTask(); 

Trả lời

3

Tôi đã gặp phải điều này trước đây và tôi nghĩ những gì bạn đang gặp phải nằm ở số here.

ToProperty/OAPH changes

  • ObservableAsPropertyHelper no longer is itself an IObservable, use WhenAny to observe it.

  • ObservableAsPropertyHelper now lazily Subscribes to the source only when the Value is read for the first time. This significantly improves performance and memory usage, but at the cost of some "Why doesn't my test work??" confusion. If you find that your ToProperty "isn't working", this may be why.

Thật lười biếng, vì vậy bạn phải đăng ký nó (nghĩa là yêu cầu giá trị từ thuộc tính nếu sử dụng OAPH) để nó hoạt động. Đó là lý do tại sao bạn nhận thấy rằng vấn đề của bạn là var startSubscription = IsLoading; 'khắc phục'.

Biết rằng điều này giúp tôi dễ dàng xác định xem đây có phải là vấn đề hay chỉ là điều cần lưu ý trong khi kiểm tra đơn vị của tôi, biết rằng ứng dụng của tôi sẽ bị ràng buộc và do đó đã đăng ký, làm cho nó tranh luận trong thực tế. Bạn biết đấy, toàn bộ cây "rơi vào rừng không có ai để nghe nó" ý tưởng.

Tôi nghĩ bạn nên gắn bó với số ToProperty mà bạn có, dường như là cách để đi IMHO.

6

and figured I should be able to do something like:

Bạn đã có ý tưởng đúng, nhưng cú pháp là một chút tắt, hãy thử:

this.LoadCommand.IsExecuting 
    .ToProperty(this, x => x.IsLoading, out _isLoading); 

Nếu bạn đã làm điều này với các đối tượng có thể thay đổi (tức là bạn đã có một biểu thức dài), có một phương pháp đặc biệt được gọi là WhenAnyObservable mà bạn sử dụng thay vì WhenAnyValue:

this.WhenAnyObservable(x => x.SomeObjectThatMightBeReplaced.IsExecuting) 
    .ToProperty(this, x => x.IsLoading, out _isLoading); 
+0

Tôi nghĩ đó là những gì tôi đã trừ đi điều này. khi bắt đầu cuộc gọi. Nó vẫn không có vẻ để hiển thị ban đầu "tải" trên kiểm soát ràng buộc của tôi trừ khi tôi đặt trong var startSubscription = IsLoading; sau cuộc gọi ToProperty. Đó là cách tôi nên giữ nó theo gợi ý của jomtois? Tôi kiểm tra điều này bằng cách thêm một sự chậm trễ 10 giây vào cuộc gọi không đồng bộ của tôi và không nhìn thấy hình ảnh "tải" của tôi trên điều khiển trừ khi tôi thêm nó. Các ràng buộc là khá đơn giản, nhưng tôi sẽ thêm nó vào câu hỏi. – RationalDev

Các vấn đề liên quan