I have a WPF application made for an LCD display with a specific resolution. The WPF application is fixed size. The view is bound to its view model by DataTemplate
s like this:
<DataTemplate DataType="{x:Type vm:IdleViewModel}">
<v:IdleView/>
</DataTemplate>
Now I would like to make this application available for a second LCD display type. The view will be totally different. Is there any way to bind the view model to a different view depending the resolution?
CodePudding user response:
There is more than one way to do this depending on your requirements. Let me focus on two different approaches that might work for you. How to find out the screen resolution is another topic, see:
Data Template Selector
You can create a data template selector that returns a DataTemplate
based on screen resolution. The mechanism to determine the screen resolution is take from the question above.
public class ResolutionDependentTemplateSelector : DataTemplateSelector
{
public DataTemplate InvalidResolutionTemplate { get; set; }
public DataTemplate Resolution1Template { get; set; }
public DataTemplate Resolution2Template { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (IsTargetResolution(480, 576))
return Resolution1Template;
if (IsTargetResolution(720, 480))
return Resolution2Template;
return InvalidResolutionTemplate;
}
private bool IsTargetResolution(double width, double height)
{
return Math.Abs(SystemParameters.PrimaryScreenWidth - width) < 1 &&
Math.Abs(SystemParameters.PrimaryScreenHeight - height) < 1;
}
}
You can assign this selector in XAML. Since I do not know which control you are using, this example uses a simple ContentControl
. The property to assign it to may vary.
<ContentControl>
<ContentControl.Resources>
<DataTemplate x:Key="Resolution1Template">
<!-- ...your markup. -->
</DataTemplate>
<DataTemplate x:Key="Resolution2Template">
<!-- ...your markup. -->
</DataTemplate>
</ContentControl.Resources>
<ContentControl.ContentTemplateSelector>
<local:ResolutionDependentTemplateSelector Resolution1Template="{StaticResource Resolution1Template}"
Resolution2Template="{StaticResource Resolution2Template}"/>
</ContentControl.ContentTemplateSelector>
</ContentControl>
Resource Dictionaries
You could create separate resource dictionaries that contain the data template for each different screen along with other specific resources that only apply to a certain screen size. Then on startup (e.g. in the App
s OnStartup
method), merge the resource dictionary that fits the screen resolution into the application resources (App.Resources
).
Depending on the size and complexity of your application you could separate the controls for each distinct screen resolution into its own project, similar to the resource dictionary approach. If the application is always run on a specific LCD type and never on another, it would also be possible to create targets for each, so each "platform" contains only the resources it needs.
CodePudding user response:
Is there any way to bind the view model to a different view depending the resolution?
Not using a single view model type and a corresponding DataTemplate
alone.
You could either
- Use two different view model types and views
- Implement the view to adopt itself according to the view model (which should then know about the current screen resolution)
- Use a DataTemplateSelector to select the appropriate view based on some logic other than just the type of the view model