Pages: << 1 ... 52 53 54 55 56 57 58 59 60 61 62 ... 105 >>

24/07/06

Permalink 02:40:59 pm
Categories: General

OneNote 2007: connection drop results in closed notebooks

I found some baffling behavior in my OneNote 2007 recently. I’m using the excellent new functionality that lets me store notebooks on my file server and open them on more than one machine. OneNote 2007 keeps automatic offline copies of these notebooks in this case, synchronizing offline changes back into the server side versions when the connection to the file server becomes available again. Really great stuff.

Problem is, it has stopped working. Well, not completely – it just started behaving completely irrationally.

I have one notebook that is stored on a remote server, accessed via VPN, and that notebooks still behaves just like it should. But for a whole bunch of notebooks that are stored on my local file server (with two exceptions, see below), the mechanism doesn’t work at all any longer. As soon as my connection (to the file server) goes away, OneNote closes these notebooks (if it’s running). If OneNote is started up while the connection is down, the notebooks are immediately closed as well. There seems to be no way to get them back without reconnecting to the server. As long as I stay connected to the server (or don’t run OneNote while I’m not connected) everything is absolutely fine. The synchronization dialog in OneNote shows me green check marks everywhere and the sync runs every minute.

I tried removing the cache for offline data (C:\Documents and Settings\Oliver\Local Settings\Application Data\Microsoft\OneNote\12.0) and it was recreated without any problems the next time I ran OneNote (with all the notebooks open). Looking at my “normal” Offline Files window, I can see two files there that are marked as “Temporarily available offline” – they have the extension .onetoc2, and the two notebooks that these files belong to are not closed completely together with all others. Instead they lose all their content (I can see the notebook “tab” on the left hand side of the window, but there are no section tabs at the top). I tried removing these two files from the Offline store, but they were recreated when I reran OneNote. Interestingly, no such entries seem to be created for any of the other notebooks I have.

Originally I thought that maybe all the section files were supposed to show up in my Offline Files window, but then there’s no entry at all for the one remote notebook that works alright. So I really have no idea what that is about – OneNote seems to use Offline File technology to work its magic, but the way it is integrated into this mechanism is not obvious to me.

Any help appreciated – I have already posted this to Microsoft’s Send a Smile feedback program, but I’m going to send them another frown now with this URL, maybe I’ll get some feedback.

21/07/06

Permalink 11:23:06 am
Categories: General, Programming, .NET

Updating a list from a thread - the UI control should do the checking

Here's one thing I have never really understood, apparently... all the time I've been using .NET, I've been working around this problem somehow. I hope somebody will be able to enlighten me, or maybe we can save the world together by finding a proper approach to this problem.

The issue is something that I'm sure most people will have encountered if they program for .NET and they ever use threads –  it's well-known and -documented. Consider the following piece of code:

  public partial class Form1 : Form {
    public Form1( ) {
      InitializeComponent( );

      dataGridView1.DataSource = list;
      Thread thread = new Thread(new ThreadStart(ChangeList));
      thread.Start();
    }

    BindingList<DataClass> list = new BindingList<DataClass>();

    public void ChangeList( ) {
      while (true) {
        int numval = list.Count + 1;
        list.Add (new DataClass("Text " + numval, numval));

        Thread.Sleep(1000);
      }
    }
  }

  public class DataClass {
    public DataClass(string strProp, int intProp) {
      this.strProp = strProp;
      this.intProp = intProp;
    }
    private string strProp;
    public string StrProp {
      get { return strProp; }
      set { strProp = value; }
    }
    private int intProp;
    public int IntProp {
      get { return intProp; }
      set { intProp = value; }
    }
  }

I guess a lot of explanation is not necessary, but the short of it is that a list of things is bound to a DataGridView and then updated from a thread. As the update happens from a thread, we have the usual crossing-into-the-UI-thread problem that is the subject of loads of newsgroup questions. Jon explains it very nicely here, so I won’t go into that. In .NET 2, this problem will result in an InvalidOperationException by default, which is a good thing because it doesn’t let you guess what the problem is, as was the case in .NET 1.

Now, my question is: What am I supposed to do about it?

I’ve been browsing the newsgroups for ideas and I was able to find a few threads about this problem, but none of them was able to offer a proper solution, or even a clear analysis of the problem. The piece of advice I usually found was: Make sure you initiate the change notification from the list on the correct (UI) thread. Pardon me, but that is no solution.

Why is that no solution? Well, there are a number of reasons:

  • It’s uncomfortable. If I’m using the BindingList<T>, as in the code sample above, there’s really no good place where to write code to check for the “correct” thread.
  • Even if I’m prepared to do the checking, what am I supposed to check against? In any proper OO program, the programmer of the collection class doesn’t know which other objects might bind to the collection’s ListChanged event later on. He also doesn’t know whether these controls are UI controls. This is not because he’s so dumb: he’s really not supposed to know, or to care, or to have to know or care.
  • Even if I found the right place, and was prepared to do the work, and actually had the means to find out which controls were bound to my list, and whether they were UI controls or not, the implementation of such checking code on the collection end of things would be extremely ugly – consider that several bound controls might be running in different UI threads, for instance.
  • Crossing over into the right UI thread (using the standard Invoke/BeginInvoke methods) is a process that involves sending Windows messages internally, which the non-UI thread code would have a hard time participating in.

The only useful conclusion I can come to when I think about this whole weird scenario is: The UI control should do the checking! Let’s see if that would be a problem:

  • The UI control obviously knows which thread it runs on.
  • The UI control knows it has to be careful not to execute any of its own code on the wrong thread – because it knows it’s a UI control (duh!)
  • When the UI control has an event handler method hooked up to an IBindingList’s ListChanged event and that handler method is called from the list, it is extremely easy for the UI control to check whether it’s in the right thread (InvokeRequired) and to change over into the right thread if necessary (Invoke/BeginInvoke).

Given my conclusion and the simplicity of the solution, I can’t help but wonder: Why don’t UI controls do this? Is there something wrong with my way of thinking? Is there an alternative approach I don’t see, with all the same advantages? Or do the programmers of UI controls not know about this problem?

Please let me know if you have any thoughts!

Update: I should probably make it clear what controls exactly I’m talking about that don’t adhere to this approach I’m suggesting: the standard Windows Forms controls in the .NET Framework. For instance, I know that the UI controls by Developer Express do use this or a similar approach and are perfectly usable with lists updated in threads.

13/07/06

Permalink 04:30:35 pm
Categories: General, Programming, .NET

Note to self - mapping of external namespaces into XAML files changed

I stumbled upon this yesterday. If an external class needs to be referenced in a XAML file, a namespace must be mapped for it, so the compiler knows where to find that class. For example, I had a DataTemplate for a specific type in my file:

  <DataTemplate DataType="{x:Type arbitraryName:Klasse}">
    <StackPanel Orientation="Horizontal">
      <TextBlock Text="{Binding Path=Name}" />
      <TextBlock Text=", Jahrgang " />
      <TextBlock Text="{Binding Path=Anfangsjahr}" />
    </StackPanel>
  </DataTemplate>

Now, the class Klasse is part of a certain namespace (Sturm.MyNamespace), in a certain assembly (Sturm.MyDataAssembly.dll), and in the many references I was able to find, it said I should have something like this in my XAML file for the mapping of the “arbitraryName” namespace:

<?Mapping XmlNamespace="arbitraryName" ClrNamespace="Sturm.MyNamespace" Assembly="Sturm.MyDataAssembly" ?>
...
<Window ...
  xmlns:arbitraryName="arbitraryName"
  ... >

The problem was that this didn’t seem to work for me – I got errors all the time saying the type “arbitraryName:Klasse” couldn’t be cast to a Type object. Finally I found the solution somewhere: Microsoft changed the syntax of this, a few months back apparently, but obviously not long enough ago judging from the number of web pages giving the old syntax. The new format doesn’t need (and actually doesn’t seem to make any use of) the Mapping instruction, and the xmlns entry has to look like this:

...
<Window ...
  xmlns:arbitraryName="clr-namespace:Sturm.MyNamespace;assembly=Sturm.MyDataAssembly"
  ... >

03/07/06

Permalink 02:34:52 pm
Categories: General, Programming, .NET

... and another event in Germany

Much sooner than Basta! (which I just blogged about) is the NRW 06 event in Duesseldorf, Germany. I’m going to be there as well, to do a talk about some of what Developer Express does, and to talk and demo to attendees directly. I’m looking forward to seeing you there!

Permalink 02:32:22 pm
Categories: General, Programming, .NET

Basta! in Germany in September

I’m going to be a speaker at Basta! in Germany, talking about the role of the model in Developer ExpresseXpressApp Framework generated applications. XAF is obviously our implementation of the general idea, but this is not supposed to be a sales pitch – the idea is generally usable, whether you like XAF or not. I got some very positive feedback about this after doing a similar thing at DDD day 3 a few weeks back.

Developer Express will also be exhibiting there, so this is the perfect time to come and ask us about eXpressApp Framework, and of course all other products.

<< 1 ... 52 53 54 55 56 57 58 59 60 61 62 ... 105 >>

Enter your email address:

Search

Oliver
MVP logo
May 2013
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31