FileUpload in UpdatePanel

Want to include a FileUpload in UploadPanel using Ajax-enabled ASP .NET WebForms?

You need to do two things:

  • Set encoding type to the form element to multi-part: <form … enctype=”multipart/form-data”>
  • Add a non-async postback trigger on the UpdatePanel for the button that you want to read the uploaded file stream on: <asp:UpdatePanel …>…<Triggers>…<asp:PostBackTrigger ControlId=”Button”/></Triggers></asp:UpdatePanel>
Posted in ASP .NET | Tagged , , , , | Leave a comment

Want to learn WPF? Get a book

Sorin Dolha's Blog

I’ve said it before. In my opinion, WPF is the single contemporary programming technology (disclaimer: among those that I’ve considered myself) that really requires a book to learn it. Otherwise, trying to dig using just hands on testing – as it’s indeed possible in many other cases – you might think you know enough before you do and you’ll get frustrated every day later because things won’t work the way you’d think they should. This StackOverflow question – that triggered this post – is only an example. I personally have been there too (and after the WPF experience, now I decided that I’ll always learn complex new technologies using books, although maybe it won’t be necessary in most cases, as it wasn’t before WPF.)

But don’t get scared. Mastering WPF by starting learning it from the core instead of from the surface will provide many, many benefits that will overcome…

View original post 137 more words

Posted in WPF | Tagged , , | Leave a comment

Features, stories, tasks: status info, hour reporting, and commits

I wrote some time ago about how you can manage a fixed priced project lifetime with Visual Studio online.

There I mentioned that status of tasks should be migrated to the upper levels of user stories and features like this (in short):

  • when a task becomes active, the parent story should also become active if it was not active already; when a story becomes active, the parent feature should also become active if it was not active already, similarily;
  • when the last task of a story becomes closed, the story becomes resolved; when the last story of a feature becomes resolved, the feature also becomes resolved;
  • when a story is tested, it status changes to closed; when the last story of a feature becomes closed, the feature also becomes closed;
  • when reopening a story, the parent feature also reopens, and at least one child bug or task (possibly newly created) becomes active.

I also talked there about using estimated and remaining effort values (in hours) for tasks, to automatically get the computed at story level. But of course, you can also report hours by adding time sheet entries under a task.

Finally, I would just like to add that when you commit and push changes (or submit change sets) as results of implementation tasks, you should also:

  • link them to the associated user stories;
  • some people would also link them to tasks (with TFS this also proposes setting the status of the task from Active to Close, but not with GIT – at least not right now); this is fine, but usually not necessary: when you want to see how a thing was implemented you check it from the story level, not from the implementation task;
  • the same applies to the feature level: usually features are used just for grouping stories, and in my opinion (gathered from my experience) you’d rarely want to see a large list of commits that make up a complex functionality (you’d check individual stories instead), so I think you can skip linking changes to features as well.
Posted in Development | Tagged , , , , , , , | Leave a comment

Change notification chaining

Sometimes you want to define a complex container that aggregates other objects and you would like to chain INotifyPropertyChanged notifications upwards. However, it is difficult to write all the code to wrap up everything needed, and often results in code duplication. So although generally I’m against inheritance in favor of aggregation, this time I think it’s OK to just have a base Changeable class as infrastructure to get the requirements fulfilled faster.

I’ve just shared the code of such a Changeable class on GitHub, packaged as a .NET Standard 1.0 library so you could use it virtually everywhere (i.e. regardless of your target platform), being available there with a small sample app that shows how it can be used. Feel free to improve it further!

Posted in .NET, C# | Tagged , , , , | Leave a comment

Naming items

From time to time I find projects with completely inconsistent naming for their items. While I believe naming things – be them source code files, variables, or enum values – is one of the most important things for the long term.

Yes, I know. For files, path length is imporant, so sometimes you cannot assign them very long names. But do name a service ComputingService instead of just Computing even if you put it into a Services namespace (folder). Still, don’t fall into the other extreme: do not prefix an item with all the namespace path from the project root. Indeed, it wouldn’t be fun to call it PublicApiSpecializedComputingService.

Another thing I want to mention here is about grouping files in project folders. While it’s fine to do it, mind the path length and do not group by multiple criteria in the same root folder. Create more sub-root folders for criteria separation, otherwise it will be strange in most IDEs. For example, have Services split into Infrastructure and Logic first, then each into Generic and Specific, if needed. I wouldn’t like a root folder with specialized logic services directly inside, and Infrastructure and Generic subfolders (and another Generic within Infrastructure) outside.

And do create Contracts folders for grouping interfaces, especially if they use hungarian notation and always start with an I: otherwise these files will end between implementation files when sorting alphabetically and most IDEs don’t even support other types of ordering for the files of a folder!

You could argue that you don’t need a Contracts folder when you have a single implementation file in the same folder with the interface, but even then sorting items in different folders may lead to inconsistent ordering and sometimes the interface would be the first, and other times the last. So I’d say it’s best to always separate contracts, even when it’s only one! You may want to even put them into different assemblies, as it would be a lot better that way if you’ll be using the (almost always mandatory) dependency injection pattern!

Finally, use var or a similar generic keyword for introducing a field or local value indicating that its type should be automatically inferred whenever it’s clear from the name but think twice otherwise. Note that to be able to reach this condition, a variable name should really fit its content, expressing as much as possible about its usage. For example, in my opinion a lagInMilliseconds field can be of type double without specifying the type, and so could be, of course, a startDateTime value of type DateTime. But don’t call the output variable of a Linq query just result or tuples: find out and use the meaning of the value since there its type would be too complex to indicate and wouldn’t clarify anything anyway, even when it’s just an intermediary step in a larger algorithm!

Posted in C# | Tagged , , , | Leave a comment

Workaround for FrameworkElement.Triggers using Style and resolving issue

Many times it would be so handy to have Triggers available at the root FrameworkElement object type. Yes, the property exists, but it only supports EventTrigger at that level, while many times you’d want a different type of trigger, such as a DataTrigger, instead. Indeed, wouldn’t it be nice to be able to write this small XAML and ensure TextBlock will move a little more down in its parent Canvas when some toggle is set on the bound data item?

<!-- Note: This code doesn't work. -->
<TextBlock Text="..." Canvas.Top="10">
  <TextBlock.Triggers>
    <DataTrigger Binding="{Binding IsToggled}" Value="True">
      <Setter Property="Canvas.Top" Value="20"/>
    </DataTrigger>
  </TextBlock.Triggers>
</TextBlock>

Hey, you say, but there is a workaround: using an inline Style. More verbose, but the expected result would be the same, no?

<!-- Note: This code still doesn't work correctly, though. -->
<TextBlock Text="..." Canvas.Top="10">
  <TextBlock.Style>
    <Style TargetType="TextBlock">
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsToggled}" Value="True">
          <Setter Property="Canvas.Top" Value="20"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>
</TextBlock>

This should be working, but it doesn’t; you can check: at runtime the trigger will have no effect. And the root issue is difficult to spot if you are not aware of the priorities used by dependency properties upon obtaining their current values. Due to those priorities, the inline property setter that is applied directly to the TextBlock will override the value set by the DataTrigger inside the Style!

To resolve the issue you just need to move the property value setter inside the Style too:

<TextBlock Text="...">
  <TextBlock.Style>
    <Style TargetType="TextBlock">
      <Setter Property="Canvas.Top" Value="10"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsToggled}" Value="True">
          <Setter Property="Canvas.Top" Value="20"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>
</TextBlock>

 

Posted in WPF | Tagged , , , , | 4 Comments

Can smartglasses replace smartphones?

As I previously mentioned I think that 3D visual user interface (provided as augmented or mixed reality, such as by Microsoft’s HoloLens) is going to be the future of app development. Accompanied, maybe, by AI-enabled voice assistants available in more languages. (Hey Siri, how are you?)

Why? Simply because of human nature: we never read manuals, do we? We always want to use a new tool or do a new thing with the skills that we already have, skipping learning as much as possible. Natural user interfaces are going to eventually replace most screens, just like the more natural touch behavior replaced most mice.

(Remember that when Windows 3.1 was introduced you had to run a mouse tutorial to learn how to use it? But no manual, nor tutorial was needed for touch gestures, although older people tend to need one simply because they were used to the old, more difficult, way to handle things.)

I was discussing about these topics with my brother a few days ago, and he asked me a few critical questions that (stupid me) I hadn’t considered before (I was just too holo-enthusiastic):

  • Do you think people would accept dragging glasses (even if they become lighter) everywhere, like they do now with their phones? People want to only carry small things that fit in their pockets, while any glasses need to be larger, don’t they?
  • What if some now unknown company, despite the current pioneers (or dinosaurs) in the field, will find a (lot) better way to do it some time later? For example, what if they’ll find an easy way to generate holograms directly from a phone into the air, without the need to project them to the eye?
    • This way people could share apps at runtime (!) by simply using their features together in the same room, without having to wear devices on their heads (while of course, online sharing will also be possible with two devices).

Indeed, I feel that the current version of HoloLens, and probably the following 2-3 models, will not fit into anyone’s pocket. (Except, maybe, those of Pete from Mickey Mouse Clubhouse; or mine.) Later they will probably become foldable or otherwise “minimizable” to the size of a nowadays phone, though. But people may still don’t like to wear things on their heads, who knows for sure?

Moreover, the second idea – that holograms may end up displaying without eye projection – sounded even more strong to me: people would definitely like to see 3D apps directly in the air of their room more than by using any type of glasses, even if they are very light and foldable to their pocket. Because not wearing a device is more natural than wearing one, no? (You are right, though: with clothes we managed to invert this!)

Still, sharing the app runtime with others in the room might not always be a good option. A setting will need to exist to allow the user to show air holograms only for himself or herself. I think this, however, will be very difficult to achieve without some eye devices from a technical point of view, but we shouldn’t underestimate science.

A possible resolution for the issue would be to go back to smartglasses and turn them into contact lens instead of having them as a head-mounted device, which means little intrusion but otherwise a safe thing. Such holographic projectors must become really tiny standalone devices to be worn on the eye and to not require any connection to a separate machine (HoloLens does this today but it’s not small enough). If they become mass-produced, I’m sure that these lens would really revolutionize our world (again).

To conclude, I think that although glasses (as a medium size device) may not be the end of the story, and that – in the new light – they might not replace smartphones at all unless they become really tiny – it depends very much on the unpredictable crowds and on science progress – for now there isn’t a better technological way to get those natural apps live. HoloLens, like any other technology, from the first PCs to the smartphones and home assistants of today, will have their life cycle, getting us closer and closer to… well… “androidization”, or at least towards the most natural interfaces for our “external” apps, which will eventually be 3D. So I still believe that focusing on HoloLens now is important for future app development – for you to be ready when the real thing will appear.

(No, I was not referring to the Android OS above, but to the fact that eventually we’d all like apps to run directly in our brains. But I acknowledge also that it would be very, very difficult for humans to accept required body implants, and people will probably be very scared to go there, and actually would have many reasons and the right to be against it. This is why I changed the goal to be just the most natural external apps we can get.)

Posted in HoloLens, Miscellaneous | Tagged , , , , | Leave a comment