Best wpf questions in October 2011

Implementing a wizard progress control in WPF

10 votes

Is there a best way to implement a control like this in WPF?

Wizard Progress Control

I can easily replicate the text labels and the progress bar (without the circular "bumps" above each label) but I'd like to know if there's a control already out there, or a best practice, for creating this sort of control in WPF.

It's hard to say what the best practice is in this case but here is how I would do it.

The wizard control in your screenshot looks like a combination of a ProgressBar and an ItemsControl and in this case it seems easier to me to derive from ItemsControl and implement the progress functionality then the other way around but it also depends on how you want it to work (if you want a smooth progress or just lit up the dots one-by-one for example).

Using a UniformGrid as ItemsPanel and the ItemTemplate below, we get the following look (Steps is a List of strings)
enter image description here

<ItemsControl ItemsSource="{Binding Steps}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Ellipse HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="Blue"/>
                <TextBlock Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Adding a DropShadowEffect to the ItemsPanel, two Path elements to the ItemTemplate and two DataTriggers to determine if the current item is the first or last item to show/hide the left/right Path and we can get a pretty similar look to your screenshot
enter image description here

ItemsPanel

<UniformGrid Rows="1" SnapsToDevicePixels="True">
    <UniformGrid.Effect>
        <DropShadowEffect Color="Black"
                          BlurRadius="5"
                          Opacity="0.6"
                          ShadowDepth="0"/>
    </UniformGrid.Effect>
</UniformGrid>

ItemTemplate

<DataTemplate>
    <DataTemplate.Resources>
        <Style TargetType="Path">
            <Setter Property="Data" Value="M0.0,0.0 L0.0,0.33 L1.0,0.33 L1.0,0.66 L0.0,0.66 L0.0,1.0"/>
            <Setter Property="StrokeThickness" Value="0"/>
            <Setter Property="Height" Value="21"/>
            <Setter Property="Stretch" Value="Fill"/>
            <Setter Property="Fill" Value="{StaticResource wizardBarBrush}"/>
            <Setter Property="StrokeEndLineCap" Value="Square"/>
            <Setter Property="StrokeStartLineCap" Value="Square"/>
            <Setter Property="Stroke" Value="Transparent"/>
        </Style>
    </DataTemplate.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Path Name="leftPath"/>
        <Path Name="rightPath" Grid.Column="1"/>
        <Ellipse Grid.ColumnSpan="2" HorizontalAlignment="Center" Height="20" Width="20" Stroke="Transparent" Fill="{StaticResource wizardBarBrush}"/>
        <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Text="{Binding}" HorizontalAlignment="Center" Margin="0,5,0,0"/>
    </Grid>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}"
                     Value="{x:Null}">
            <Setter TargetName="leftPath" Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={markup:IsLastItemConverter}}"
                     Value="True">
            <Setter TargetName="rightPath" Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

If you decide to use this approach you can probably workout how to get the rest of it going, like

  • Implement this in a resuable custom control
  • Only get the stroke (DropShadowEffect) on the progress-part and not in the text
  • Implement the progress functionality etc.

Anyway, I uploaded a sample project with a custom control called WizardProgressBar and a demo project using it here: http://dl.dropbox.com/u/39657172/WizardProgressBarDemo.zip

It looks like this
enter image description here

Things to note about the sample

  • I ended up in a situation where I would get the DropShadowEffect on the progress-part and the headers or get a thin line between each item (as seen in the picture). I can't think of an easy way to get rid of it so maybe this isn't the best approach after all :)
  • The progress-part is simple. It just has a value between 0-100 and then a converter decides if the item should be lit or not
  • This control might have a small performance impact but I can't be sure since my computer seems to be running everything slow today..

Update

Made a few changes to the sample project where I splitted the presentation into two ItemsControls to get rid of the thin lines between each item. It now looks like this
enter image description here
Uploaded it here: http://dl.dropbox.com/u/39657172/WizardProgressBarDemo2.zip

End of Update

And here are the missing parts from the sample code above

<LinearGradientBrush x:Key="wizardBarBrush" StartPoint="0.5,0.0" EndPoint="0.5,1.0">
    <GradientStop Color="#FFE4E4E4" Offset="0.25"/>
    <GradientStop Color="#FFededed" Offset="0.50"/>
    <GradientStop Color="#FFFCFCFC" Offset="0.75"/>
</LinearGradientBrush>

IsLastItemConverter

public class IsLastItemConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ContentPresenter contentPresenter = value as ContentPresenter;
        ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(contentPresenter);
        int index = itemsControl.ItemContainerGenerator.IndexFromContainer(contentPresenter);
        return (index == (itemsControl.Items.Count - 1));
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public IsLastItemConverter() { }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

Why does the binding update without implementing INotifyPropertyChanged?

10 votes

I created a ViewModel and bound its property to two textboxes on UI. The value of the other textbox changes when I change the value of first and focus out of the textbox but I'm not implementing INotifyPropertyChanged. How is this working?

Following is XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding Name}" />
        <TextBox Text="{Binding Name}" />
    </StackPanel>
</Window>

And following is my ViewModel

class ViewModel
{
    public string Name { get; set; }
}

I tested it, you are right. Now i searched for it on the web, and found this.

Sorry to take so long to reply, actually you are encountering a another hidden aspect of WPF, that's it WPF's data binding engine will data bind to PropertyDescriptor instance which wraps the source property if the source object is a plain CLR object and doesn't implement INotifyPropertyChanged interface. And the data binding engine will try to subscribe to the property changed event through PropertyDescriptor.AddValueChanged() method. And when the target data bound element change the property values, data binding engine will call PropertyDescriptor.SetValue() method to transfer the changed value back to the source property, and it will simultaneously raise ValueChanged event to notify other subscribers (in this instance, the other subscribers will be the TextBlocks within the ListBox.

And if you are implementing INotifyPropertyChanged, you are fully responsible to implement the change notification in every setter of the properties which needs to be data bound to the UI. Otherwise, the change will be not synchronized as you'd expect.

Hope this clears things up a little bit.

So basically you can do this, as long as its a plain CLR object. Pretty neat but totally unexpected - and i have done a bit of WPF work the past years. You never stop learning new things, right?

As suggested by Hasan Khan, here is another link to a pretty interesting article on this subject.

Note this only works when using binding. If you update the values from code, the change won't be notified. [...]

WPF uses the much lighter weight PropertyInfo class when binding. If you explicitly implement INotifyPropertyChanged, all WPF needs to do is call the PropertyInfo.GetValue method to get the latest value. That's quite a bit less work than getting all the descriptors. Descriptors end up costing in the order of 4x the memory of the property info classes. [...]

Implementing INotifyPropertyChanged can be a fair bit of tedious development work. However, you'll need to weigh that work against the runtime footprint (memory and CPU) of your WPF application. Implementing INPC yourself will save runtime CPU and memory.

Prevent memory leaks in WPF

7 votes

Working with WinForms you have to free memory after using gdi objects, event handlers, objects from native code, etc.

In WinForms I used to remove for example event handlers in the dispose method.

What is the best workaround to prevent memory leaks in Wpf? Is it the same as in Winforms using Dispose pattern? At all, do I have to care about event handlers, gdi objects in Wpf? What about the runtime created resources(Brushes, etc)?

This blog post lists the most common situations that cause memory leaks in WPF applications.

  • Event handlers to objects in parent windows
  • Registering to events from static objects
  • Using timers
  • Data binding
  • Changing the Text property of a text box

It also describes how to fix these common issues.

Another good approach is to develop an app while following the standard guidelines and then use some kind of profiler to determine any memory leaks or performance bottlenecks.

How Get The middle point of an ArcSegment in WPF

Asked on Sat, 15 Oct 2011 by ARZ c# wpf
7 votes

What is the best solution for getting the middle point of an ArcSegment in a path and label it in WPF?

enter image description here

This should work:

        //the given arc (or any other segments)
        var arc = new ArcSegment(
            point: new Point(200, 100),
            size: new Size(100, 50),
            rotationAngle: 90,
            isLargeArc: true,
            sweepDirection: SweepDirection.Counterclockwise,
            isStroked: true);

        //compose one or more segments into a collection
        var pathcoll = new PathSegmentCollection();
        pathcoll.Add(arc);

        //create a figure based on the set of segments
        var figure = new PathFigure();
        figure.Segments = pathcoll;

        //compose a collection of figures
        var figcoll = new PathFigureCollection();
        figcoll.Add(figure);

        //create a path-geometry using the figures collection
        var geom = new PathGeometry(figcoll);

        double fraction = 0.5;  //the relative point of the curve
        Point pt;               //the absolute point of the curve
        Point tg;               //the tangent point of the curve
        geom.GetPointAtFractionLength(
            fraction,
            out pt,
            out tg);

Hope it helps.

Cheers

is WPF THE choice for windows apps?

7 votes

I am developping in Ironpython with Visual Studio 2010 through PTVS.

I see that WPF is quite slow compared to the silverlight equivalent... at least to me. My program does a lot of calculations but the user interface is really simple. I have read lots of WPF vs Silverlight questions and this one too. I heard about silverlight out-of-browser mode... I don't know what to think about it.

I am a little bit confused, I need my application to be fast, I don't need much things concerning the user interface. It is a windows app only, it is only destined to run on the user computer.

so, is wpf actually the best choice in this case?

Thanks

To be honest, contrary to all the other comments. I use WPF even for simple applications. In fact it really helps avoiding alot of necessary code on other ui frameworks. I like the fact that using WPF i can directly think about the data i'm going to modify, without writing alot of event handlers for adding items to collection, showing them in a list etc. Also WPF is not bound to use MVVM, just use a class that combines both view model and model. After using WPF alot, i can't imagine to use Windows Forms again.

But of course this is just my personal opinion. In the end always use the tool best suited for your problem at hand. If you don't know WPF and you want to use it just for a small applications, i would suggest windows forms or something else.

Delay property on Binding from .Net 4.5 in .Net 4.0

6 votes

How can I implement Delay property from .Net 4.5 (described here) on binding in .Net 4.0?

I know I cannot inherit from BindingBase as ProvideValue is sealed.

I could implement MarkupExtension but it means I now have to rewrite all properties from BindingExtension is there any other way?

I would create an AttachedProperty that specifies the amount of time to Delay. The AttachedProperty would start (or reset) a timer when the bound value changes, and would manually update the bound source when the specified amount of time gets reached.

You can use the following to update the source binding:

BindingOperations.GetBindingExpressionBase(
    dependencyObject, dependencyProperty).UpdateSource();

Edit

I was fixing a bug in some old code today and noticed it implemented a delayed property change notification using an Attached Behavior. I thought of this question, so followed the link that I had commented in the code, and found myself at a question I had posted a while ago on SO about delaying a binding. The top answer is the one I have implemented currently, which is some attached properties that updates the source of a binding after X milliseconds have passed.

I'm very new to threading. I hope someone can give me some example.

I'm trying to start a thread when user click on start button and do the following process:

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    if (serialPort.IsOpen)
        serialPort.Close();
    try
    {
        //To set all the parameters for Serial Comm
        serialPort.PortName = "COM14";
        serialPort.BaudRate = int.Parse("38400");
        serialPort.Parity = Parity.None;
        serialPort.DataBits = 8;
        serialPort.StopBits = StopBits.One;
        serialPort.Encoding = System.Text.Encoding.ASCII;

        serialPort.DataReceived += new SerialDataReceivedEventHandler(GotRawData);

        serialPort.Open();

        //To show that Com Port is Opened
        txtboxOutput.AppendText(DateTime.Now.ToString("hh:mm:ss tt") + " - COM14 is opened." + Environment.NewLine);
        txtboxOutput.ScrollToEnd();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message.ToString());
    }
}

private void GotRawData() is a method where i do something to get some raw data from a hardware.

You might find the System.ComponentModel.BackgroundWorker class rather useful which in my understanding is the simplest way to execute an operation on a separate thread.

How can I manually tell an owner-drawn WPF Control to refresh?

6 votes

We are doing custom drawing in a control subclass's OnRender. This drawing code is based on an external trigger and data. As such, whenever the trigger fires, we need to re-render the control based on that data. What we're trying to do is find out how to force the control to re-render but without going through an entire layout pass.

As stated above, most answers I've seen revolve around invalidating the Visual which invalidates the layout which forces new measure and arrange passes which is very expensive, especially for very complex visual trees as ours is. But again, the layout does not change, nor does the VisualTree. The only thing that does is the external data which gets rendered differently. As such, this is strictly a pure rendering issue.

Again, we're just looking for a simple way to tell the control that it needs to re-execute OnRender. I have seen one 'hack' in which you create a new DependencyProperty and register it with 'AffectsRender' which you just set to some value when you want to refresh the control, but I'm more interested in what's going on inside the default implementation for those properties: what they call to affect that behavior.


Update:

Well, it looks like there isn't any such call as even the AffectsRender flag still causes an Arrange pass internally (as per CodeNaked's answer below) but I've posted a second answer that shows the built-in behaviors as well as a work-around to suppress your layout pass code from running with a simple nullable size as a flag. See below.

Unfortunately, you must call InvalidateVisual, which calls InvalidateArrange internally. The OnRender method is called as part of the arrange phase, so you need to tell WPF to rearrange the control (which InvalidateArrange does) and that it needs to redraw (which InvalidateVisual does).

The FrameworkPropertyMetadata.AffectsRender option simply tells WPF to call InvalidateVisual when the associated property changes.

If you have a control (let's call this MainControl) that overrides OnRender and contains several descendant controls, then calling InvalidateVisual may require the descendant controls to be rearranged, or even remeasured. But I believe WPF has optimizations inplace to prevent descendant controls from being rearranged if their available space is unchanged.

You may be able to get around this by moving your rendering logic to a separate control (say NestedControl), which would be a visual child of MainControl. The MainControl could add this as a visual child automatically or as part of it's ControlTemplate, but it would need to be the lowest child in the z-order. You could then expose a InvalidateNestedControl type method on MainControl that would call InvalidateVisual on the NestedControl.

Best way to get a user to input a correctly-formatted URL?

6 votes

I am creating a dialog using MVVM which prompts the user to type in an http:// URL to a KML file. The "OK" button needs to be enabled when the URL is in the correct format, and it needs to be disabled when the URL is in an incorrect format.

Right now the button is bound to an ICommand, and the logic for CanExecute() looks like this:

return !string.IsNullOrEmpty(CustomUrl);

The command's CanExecuteChanged event is raised on every keystroke, and so far it's working well.

Now I want to do a little bit of actual validation. The only way I know to do that is as follows:

try
{
    var uri = new Uri(CustomUrl);
}
catch (UriFormatException)
{
    return false;
}

return true;

That's no bueno, especially since the validation is happening on each keystroke. I could make it so that the URI is validated when the user hits the OK button, but I'd rather not. Is there a better way to validate the URI other than catching exceptions?

Yes - you can use the static method Uri.IsWellFormedUriString for this

return Uri.IsWellFormedUriString (CustomUrl, UriKind.Absolute);

The model in MVVM

6 votes

Unless I misunderstand - Most of the articles I read on MVVM explains model in MVVM as the piece holding domain/business-logic, but what baffles me is that MVVM is a presentation layer pattern and presentation layer does not hold business logic in entirety. Can some please help me understand how the domain-logic in business layer maps to the model in the presentation layer, is the model in MVVM actually a DTO? I'd appreciate if some one can help explain with an example how business layer is mapped to a MVVM model in SOA (business logic sits behind a web service). Thanks.

MVVM, like MVC, is just a form of Separated Presentation in which the intent is to achieve separation of concerns between the part of the applicaton concerned with the logic and state of the UI and the part of the application concerned with the logic and state relating to the business domain. So MVVM doesn't really dictate anything about the form that the Model part takes as long as it is separated from presentation concerns.

The Model is purposely not coupled or dependent in any way on the presentational aspects of the application but beyond that there are many different ways to implement the "M" part of the triad. In particular, it doesn't have to map to a single object: it could mean interacting with a service that returns DTOs, it could mean publishing and subscribing to messages on a message bus or it could mean retrieving domain objects that represent entities in your domain, calling methods on them and then persisting them.

What's really unique about the MVVM pattern is the ViewModel's role in it since its purpose is to represent the state of the UI in a way that can be consumed by View technologies that have rich databinding capabilities. Without rich databinding support you would use a different form of Separated Presentation such as MVC or MVP, but the "M" part could still be the same because it's independent of the UI technology by definition. That is the important factor.

How to do datatemplate for items in listbox?

5 votes

I have an XML file (see below) and can display all the Product Names in a listbox. I want each entry in the listbox to display Product Name followed by Price, not just Product Name.

How do I do the datatemplate in the XAML file? Thanks.

Simplified XML file:

<Product> 
<Name>Red Chair</Name> 
<Price>29.5</Price>  
</Product>

Simplified XAML file:

<DockPanel>      
<ListBox Name="listBox1" ItemsSource="{Binding}" Margin="10" >      
</ListBox> 
</DockPanel> 

In my C# file, I use LINQ to collect the products from the XML file and assign var products to listBox1.DataContext and it works fine. Now I just want to add in the Price. Thanks.

You do this the same as any other ItemTemplate.

Make sure that you're binding to the Product, not the Name. You can then select the values from the XML using XPath, something like this.

<DockPanel>
  <ListBox Name="listBox1" 
           ItemsSource="{Binding}" 
           Margin="10" >       
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel>
          <TextBlock Text={Binding XPath=./Name} />
          <TextBlock Text={Binding XPath=./Price} />
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</DockPanel>

.NET application cannot start

5 votes

I wrote an app that can install and work on my development PC (a Window 7).

  • Development Environment: Window 7, VS2010 WPF C# with both .NET 4 and .NET 3.5 installed

On other client computer (XP SP3, 2 and 1), it install with no error, but can not start. In task manager, I can see the application takes up memory briefly before closing by itself.

I had made sure .NET 3.5 consistency across my develop PC and various client XP machines by following:

  • The application targets .NET 3.5 (or 3.5 Client Profile)
  • Use VS2010 Installer for deployment: targets .NET 3.5 in Launch Condition
  • No error whatsoever about .NET compatibility during debug of application and installer project

eventvwr caught the following warning:

 ¬º˛¿‡–Õ:   ¥ÌŒÛ
 ¬º˛¿¥‘¥:   .NET Runtime
 ¬º˛÷÷¿‡:   Œfi
 ¬º˛ ID:    1026
»’∆⁄:       2011-10-18
 ¬º˛:       15:18:32
”√ªß:       N/A
º∆À„ª˙: WWW-9DB69D5A3AF
√Ë ˆ:
Application: Foo.exe
Framework Version: v4.0.30319
Description: ”…”⁄Œ¥æ≠¥¶¿Ìµƒ“Ï≥££¨Ω¯≥Ã÷’÷π°£
“Ï≥£–≈œ¢: System.Windows.Markup.XamlParseException
∂—’ª:
   ‘⁄ System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri)
   ‘⁄ System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader, System.Xaml.IXamlObjectWriterFactory, Boolean, System.Object, System.Xaml.XamlObjectWriterSettings, System.Uri)
   ‘⁄ System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader, Boolean, System.Object, System.Xaml.Permissions.XamlAccessLevel, System.Uri)
   ‘⁄ System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream, System.Windows.Markup.ParserContext, System.Object, Boolean)
   ‘⁄ System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream, System.Windows.Markup.ParserContext)
   ‘⁄ System.Windows.Application.LoadComponent(System.Uri, Boolean)
   ‘⁄ System.Windows.Application.DoStartup()
   ‘⁄ System.Windows.Application.<.ctor>b__1(System.Object)
   ‘⁄ System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   ‘⁄ MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   ‘⁄ System.Windows.Threading.DispatcherOperation.InvokeImpl()
   ‘⁄ System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(System.Object)
   ‘⁄ System.Threading.ExecutionContext.runTryCode(System.Object)
   ‘⁄ System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
   ‘⁄ System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   ‘⁄ System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   ‘⁄ System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   ‘⁄ System.Windows.Threading.DispatcherOperation.Invoke()
   ‘⁄ System.Windows.Threading.Dispatcher.ProcessQueue()
   ‘⁄ System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   ‘⁄ MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   ‘⁄ MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   ‘⁄ System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   ‘⁄ MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   ‘⁄ System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   ‘⁄ MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
   ‘⁄ MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
   ‘⁄ System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
   ‘⁄ System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame)
   ‘⁄ System.Windows.Threading.Dispatcher.Run()
   ‘⁄ System.Windows.Application.RunDispatcher(System.Object)
   ‘⁄ System.Windows.Application.RunInternal(System.Windows.Window)
   ‘⁄ System.Windows.Application.Run(System.Windows.Window)
   ‘⁄ System.Windows.Application.Run()
   ‘⁄ FooSoftware.App.Main()


”–πÿ∏¸∂‡–≈œ¢£¨«Î≤Œ‘ƒ‘⁄ http://go.microsoft.com/fwlink/events.asp µƒ∞Ô÷˙∫Õ÷ß≥÷÷––ƒ°£

there was this XamlParseException causing my app to not start on XP Window Machine. What is going on?

XamlParseException is the generic error that happens when there is a problem at application start. I suggest you modify you application startup code to trace what's really going on and get, not only the XamlParseException, but also the inner exception(s) which should help you determine the root of the problem. Here is an example:

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            // hook on error before app really starts
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            base.OnStartup(e);
        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // put your tracing or logging code here (I put a message box as an example)
            MessageBox.Show(e.ExceptionObject.ToString());
        }
    }
}

How to convert from an 'hermite' curve into bezier curve?

5 votes

As the topic states: How to convert from an Hermite curve into Bezier curve? Specifically I'm looking for a way to convert the Curve class, that uses Hermite interpolation, of the Microsoft XNA Framework to be drawn with StreamGeometry or PathGeometry of Windows Presentation Foundation.

I've come across a similar question ([http://stackoverflow.com/questions/1030596/drawing-hermite-curves-in-opengl][1]) where the answer is the following.

[b0] = 1 [ 3  0  0  0] [h0]
[b1]   - [ 3  0  1  0] [h1]
[b2]   3 [ 0  3  0 -1] [v0]
[b3]     [ 0  3  0  0] [v1]

Which simplifies to:

B0 = P0
B1 = P0 + V0/3
B2 = P1 - V1/3
B3 = P1

Even with this information I'm in essence stuck on computing the control points. The Problem is that Curve class exposes a TangentIn and TangentOut as a scalar. Given that drawing of the polynomial occurs in 2-dimensional space (time, value) this scalar needs to be converted into a 2-dimensional vector in order to apply it to that formula. However I'm unsure what the steps are involved of this conversion process but I suspect I need to apply the Hermite differentiation equation.

If it helps this is the code used to evaluate the curve at a given moment as found with Reflector.

private static float Hermite(CurveKey k0, CurveKey k1, float t)
{
     if (k0.Continuity == CurveContinuity.Step)
     { 
         if (t >= 1f)
         {
             return k1.internalValue;
         }
         return k0.internalValue;
     }

     float num = t * t;
     float num2 = num * t;
     float internalValue = k0.internalValue;
     float num5 = k1.internalValue;
     float tangentOut = k0.tangentOut;
     float tangentIn = k1.tangentIn;
     return ((((internalValue * (((2f * num2) - (3f * num)) + 1f)) + (num5 * ((-2f * num2) + (3f * num)))) + (tangentOut * ((num2 - (2f * num)) + t))) + (tangentIn * (num2 -  num)));
}

Any information is much appreciated.

I've never used XNA, but having glanced at the documentation it seems that the Curve class corresponds to a one-dimensional Bezier curve. The conversion formula you quote should work fine: the "coordinates" in a one dimensional Bezier curve are all scalars.

Hence it doesn't really make sense to try to plot a single XNA Curve as a two-dimensional Bezier curve. The Curve time value corresponds to the Bezier parameter t, not one of the spatial axes.

As it says in the Curve class documentation: "To represent a time path in two or three dimensions, you can define two or three Curve objects, each of which corresponds to a different spatial axis."

i.e. you need two Curve objects, one to provide the x value and one to provide the y value at a particular time.

How to add comments into a Xaml file in WPF?

4 votes

I used this syntax as I found online but it throws an error:

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Cool comment -->
xmlns:System="clr-namespace:System;assembly=mscorlib"

'Name cannot begin with the '<' character, hexadecimal value 0x3C. Line 4, position 5.' XML is not valid.

I assume those XML namespace declarations are in the parent tag of your control? You can't put comments inside of another tag. Other than that, the syntax you're using is correct.

<UserControl xmlns="...">
    <!-- Here's a valid comment. Notice it's outside the <UserControl> tag's braces -->
    [..snip..]
</UserControl>