2011-07-05 24 views
5

Tôi có ứng dụng Silverlight 4 với PRISM 4, tôi đang sử dụng MEF.Lăng kính 4 - phạm vi cục bộ RegionManager

Shell của tôi xác định một vùng chính trong đó các mô-đun được tải, tôi muốn các mô-đun có Trình quản lý vùng riêng của mình, do đó các vùng mà chúng xác định là các địa điểm trong RegionManager cục bộ thay vì toàn cục. Và tôi muốn RegionManager cục bộ này được giải quyết bằng container (đối với kiểu IRegionManager) khi bên trong module.

Tuy nhiên phương pháp từ tài liệu:

IRegion detailsRegion = this.regionManager.Regions["DetailsRegion"]; 
View view = new View(); 
bool createRegionManagerScope = true; 
IRegionManager detailsRegionManager = detailsRegion.Add(view, null, 
          createRegionManagerScope); 

doesnt làm việc cho tôi, khi giải quyết IRegionManager từ bên trong nhìn con tôi vẫn nhận được GlobalRegionManager.

Trả lời

10

Tôi đã ở trong tình trạng tương tự như bạn, tôi đã có một người quản lý khu vực lồng nhau, nhưng tất cả các lượt xem con vẫn nhận được người quản lý khu vực toàn cầu. Tôi nghĩ ra một giải pháp hợp lý.

Trước tiên tôi xác định một giao diện:

/// <summary> 
/// An interface which is aware of the current region manager. 
/// </summary> 
public interface IRegionManagerAware 
{ 
    /// <summary> 
    /// Gets or sets the current region manager. 
    /// </summary> 
    /// <value> 
    /// The current region manager. 
    /// </value> 
    IRegionManager RegionManager { get; set; } 
} 

Sau đó, tôi thiết lập một RegionBehavior như vậy:

/// <summary> 
/// A behaviour class which attaches the current scoped <see cref="IRegionManager"/> to views and their data contexts. 
/// </summary> 
public class RegionAwareBehaviour : RegionBehavior 
{ 
    /// <summary> 
    /// The key to identify this behaviour. 
    /// </summary> 
    public const string RegionAwareBehaviourKey = "RegionAwareBehaviour"; 

    /// <summary> 
    /// Override this method to perform the logic after the behaviour has been attached. 
    /// </summary> 
    protected override void OnAttach() 
    { 
     Region.Views.CollectionChanged += RegionViewsChanged; 
    } 

    private void RegionViewsChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     Contract.Requires<ArgumentNullException>(e != null); 

     if (e.NewItems != null) 
      foreach (var item in e.NewItems) 
       MakeViewAware(item); 
    } 

    private void MakeViewAware(object view) 
    { 
     Contract.Requires<ArgumentNullException>(view != null); 

     var frameworkElement = view as FrameworkElement; 
     if (frameworkElement != null) 
      MakeDataContextAware(frameworkElement); 

     MakeAware(view); 
    } 

    private void MakeDataContextAware(FrameworkElement frameworkElement) 
    { 
     Contract.Requires<ArgumentNullException>(frameworkElement != null); 

     if (frameworkElement.DataContext != null) 
      MakeAware(frameworkElement.DataContext); 
    } 

    private void MakeAware(object target) 
    { 
     Contract.Requires<ArgumentNullException>(target != null); 

     var scope = target as IRegionManagerAware; 
     if (scope != null) 
      scope.RegionManager = Region.RegionManager; 
    } 
} 

Sau đó, áp dụng điều này để tất cả các vùng trong bootstrapper của bạn:

protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors() 
{ 
    var behaviours = base.ConfigureDefaultRegionBehaviors(); 

    behaviours.AddIfMissing(RegionAwareBehaviour.RegionAwareBehaviourKey, typeof(RegionAwareBehaviour)); 

    return behaviours; 
} 

Sau đó, tất cả những gì bạn phải làm là triển khai IRegionManagerAware trên chế độ xem/chế độ xem của bạn, có thể như sau:

public class MyView : IRegionManagerAware 
{ 
    IRegionManager RegionManager { set; get; } 
} 

Sau đó, khi chế độ xem này được thêm vào khu vực, hành vi sẽ đặt chính xác thuộc tính RegionManager cho người quản lý khu vực hiện tại.

+1

Rất đẹp. Tôi vẫn đang sử dụng PRISM, nhưng nó gần như được viết lại hoàn toàn. Prism có kiến ​​trúc mở rộng đẹp. –

+1

Hoạt động tuyệt vời. Tôi chỉ vô hiệu hóa các Hợp đồng – lvmeijer

2

Nếu bạn đọc dòng tiếp theo trong tài liệu, nó nói "Phương thức Thêm sẽ trả về Trình quản lý vùng mới mà chế độ xem có thể giữ lại để truy cập thêm vào phạm vi cục bộ".

vì vậy tôi sẽ tạo thuộc tính trong chế độ xem và chuyển IRegionManger cho nó.

bên trong chế độ xem/chế độ xemMô hình.

public IRegionManager rm { get; set; } 

sau đó vượt qua IregionManager mà được trả lại sau khi thêm cái nhìn mới

view.rm = detailsRegionManager; 

Hy vọng rằng sẽ giúp.

+2

thực sự, tôi dự kiến ​​nó sẽ chuyển thành IoC và xử lý đúng RegionManager, nhưng có vẻ như bạn cần tự quản lý nó. –

+0

@AlexBurtsev Hãy xem câu trả lời gần đây của tôi, tôi tin rằng tôi đã tìm thấy một giải pháp để tự kết nối tất cả. – Lukazoid

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