W xaml'u wyglądałoby to mniej więcej w ten sposób:
<Grid ...>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<ContentControl Regions:RegionManager.RegionName="LogoRegion" Grid.ColumnSpan="2"/>
<ContentControl Regions:RegionManager.RegionName="NavigatorRegion" Grid.Row="1"/>
<ContentControl Regions:RegionManager.RegionName="MainRegion" Grid.Column="1" Grid.Row="1"/>
</Grid>
Tak jak widać powyżej regiony definiujemy poprzez AttachedProperty RegionName klasy RegionManager. Od tej pory jeżeli w kodzie wywołamy następującą metodę:
regionManager.Regions["MainRegion"].Activate(view);
w obszarze "MainRegion" pojawi się nasz widok. Oznacza to tyle samo, że właściwość Content naszej ContentControl zostanie wypełniona obiektem "view". Oczywiście regiony mogą być zagnieżdżone jeden w drugim i Prism bez problemu poradzi sobie z taką sytuacją.
Powyższe rozwiązanie aktywacji widoku powinno być opakowane w jakiś obiekt pośredni. Nie zawsze bowiem mamy dostęp do obiektu widoku, w momencie gdy chcemy go aktywować. Naturalny wydaje się poniższy zapis:
ViewService.ActivateView(Type type);
ViewService.ActivateView(string viewName);
W pierwszym zapisie tak czy inaczej musimy mieć dostęp do typu widoku. Drugie rozwiązanie wydaje się bardziej elastyczne. Możemy je zaimplementować bez konieczności dołączania referencji do projektu z interfejsem graficznym. Przykładowy kod może wyglądać tak:
public void ActivateView(string viewName)
{
foreach (IRegion region in regionManager.Regions)
{
object view;
if (RegionContainsViewName(region, viewName, out view))
{
region.Activate(view);
break;
}
}
}
Na koniec mała wskazówka jeżeli chodzi o utrzymanie kodu. Nasz kod może być trudny w utrzymaniu, jeżeli np. chcemy zmienić nazwę regionu dlatego dobrą praktyką jest trzymanie nazw jako stałych. Jest to bardzo proste do rozwiązania w WPF'ie, gdzie możemy się odwoływać do stałych poprzez x:Static. Jeżeli chodzi o Silverlight warto zastosować pewne obejście:
<Grid.Resources>
<ResourceDictionary>
<Resources:Names x:Key="Names"/>
</ResourceDictionary>
</Grid.Resources>
...
<ContentControl Regions:RegionManager.RegionName="{Binding NavigatorRegion, Source={StaticResource Names}}"/>
<ContentControl Regions:RegionManager.RegionName="{Binding MainRegion, Source={StaticResource Names}}"/>
gdzie klasa Names może wyglądać następująco:
public class Names
{
public string MainRegion { get { return "MainRegion"; } }
public string NavigatorRegion { get { return "NavigatorRegion"; } }
}
0 komentarze:
Prześlij komentarz