简体   繁体   中英

What is the best way to show an inherited object in wpf?

Lets say I have this:

public class Result 
{
   public bool Success { get; set; }
   public string Description { get; set; }
}

Then I want to add another level, like this:

public class AssertionFailedResult : Result
{
  public string Expected { get; set; }
  public string Actual { get; set; }
}

In WPF, how would I show the simple result one way and the assertion failed result another way? I'd like to basically make a template based on type.

If you create a DataTemplate in a resource dictionary and set the DataType property, but don't set the x:Key property, the framework will associate the DataTemplate to objects based on the object's runtime type. For better or worse, inheritance has no effect. In other words, even if you didn't have a template where the DataType was "AssertionFailedResult", the framework would not bind objects of type "AssertionFailedResult" to a template where the DataType was "Result".

EDIT: Sorry, I got it backwards. DataTemplates do have a "polymorphic" behavior. Styles do not. In any case, the frameworks should bind to the DataTemplate with the more specific DataType.

I took Daniel's answer and made an example out of it. I thought posting the code might be helpful:

<Window x:Class="SampleWpfApplication.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:SampleWpfApplication="clr-namespace:SampleWpfApplication">
    <Window.Resources>
        <DataTemplate DataType="{x:Type SampleWpfApplication:Result}">
            <Label>Simple Result</Label>            
        </DataTemplate>
        <DataTemplate DataType="{x:Type SampleWpfApplication:AssertionFailedResult}">
            <Label>Assertion Failed!</Label>
        </DataTemplate>
    </Window.Resources>
    <ContentControl x:Name="contentControl" Content="{Binding Path=Result}" />
</Window>

Next, a model class that is the data context of the window:

public class Model
{
    public Result Result { get; set; }
}

And in the MainWindow, I set the DataContext as follows:

DataContext = new Model()
                  {
                      Result = new AssertionFailedResult()
                                   {
                                       Success = false,
                                       Description = "Assertion failed",
                                       Expected = "1",
                                       Actual = "1"
                                   }
                  };

So with the DataTemplate, wpf knows how to render the control without any additional direction on my part. Thanks again, Daniel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM