.
Anmeldung | Registrieren | Hilfe
Suchen
Home Foren News Member Offers Termine Developer Blogs Knowledge Base

Verknüpfungen

  • RSS Feed
  • Twitter

Developer

  • Albert Weinert
  • Alexander Groß
  • Alexander Zeitler
  • Andre Kraemer
  • Andre Loker
  • Andreas Mehl
  • Andreas Seebauer
  • Bernd Hengelein
  • Boas Enkler
  • Christian Binder
  • Christian Weyer
  • Christina Hirth
  • Constantin Klein
  • Daniel Schädler
  • Daniel Springwald
  • Dariusz Parys
  • Dariusz Parys
  • dotnet-kicks.de Blog
  • Gordon Breuer
  • Gregor Biswanger
  • Ilker Cetinkaya
  • Jan Christian Selke
  • Jan Schenk
  • Jan Welker
  • Jan-Cornelius Molnar
  • Jens Häupel
  • Jens Peter Kleinau
  • Jochen Kalmbach
  • Julian Amann
  • Jürgen Gutsch
  • Kay Giza
  • Klaus Bock
  • Lars Keller
  • Lars Schmitt
  • Lori Grosland
  • Mario Meir-Huber
  • Mario Priebe
  • Martin Hey
  • Mathias Gronau
  • Mathias Raacke
  • Michael Hülskötter
  • Michael Schwarz
  • Microsoft Press
  • Nico Franze
  • Norbert Eder
  • Oliver Guhr
  • Oliver Scheer
  • Oliver Scheer
  • Otto Fischer
  • Ozgur Aytekin
  • Patrick Sperneder
  • Paul Mizel
  • Peter Bucher
  • Peter Kirchner
  • Rainer Hilmer
  • Rainer Schuster
  • Ralf Westphal
  • Rene Drescher-Hackel
  • Rene Muster
  • Rene Paschold
  • Robert Mühsig
  • Robert Wachtel
  • Roland Weigelt
  • Rong Lu
  • Sascha Baumann
  • Sebastian Gerling
  • Sebastian Jancke
  • Stefan Falz
  • Stefan Kölle
  • Stefan Lange
  • Stefan Lieser
  • Steffen Krause
  • Steffen Ritter
  • Thomas Christian
  • Thomas Freudenberg
  • Thomas Mentzel
  • Thomas Schissler
  • Thorsten Hans
  • Timo Rehl
  • Wolfgang Kluge

.NET Developer Blogs Twitter

Vorträge von der CeBit: Office 2010, SharePoint 2010, Business Intelligence

15.03.2010 17:27:08 | Steffen Krause

Auf der CeBit haben Tom Wendel und ich auch Vorträge zu Office 2010 und SharePoint 2010 gehalten Her nun die Videos: TechNet: Business Intelligence mit der Microsoft Plattform MSDN: Sharepoint 2010 / Office 2010 TechNet: Office 2010 – ein Überblick TechNet:...(read more)

Office 2007-VSTO AddIns für ALLUSERs

15.03.2010 16:13:30 | Jens Häupel

bekanntlich verhindert ja Office 2007, dass VSTO-AddIns (managed Code) von HKLM geladen werden. LoadBehavior wird dabei immer wieder auf 2 zurückgestellt.

Das Office Team hat jetzt (nachdem Office 2010 das sowieso wieder erlaubt) auch einen Patch für Office 2007 herausgebracht, der diese Möglichkeit wieder erlaubt:

A 2007 Office system application does not load an add-in that is developed by using VSTO

http://support.microsoft.com/kb/976811

Beachten sollte man allerdings, dass der (Standard-) Benutzer diese AddIns nicht deaktivieren kann!

Weitere Infos:

In Microsoft Office 2003 and earlier, COM add-ins could be registered in HKEY_LOCAL_MACHINE and this had the following effects:

• They were available for all Windows user profiles

• They did not appear in the COM Add-ins window so therefore the user could not remove the add-in.

In the original version of Office 2007, this behavior was changed so that add-ins developed using Visual Studio Tools for Office (VSTO) and registered in HKEY_LOCAL_MACHINE would not load. In addition, Office 2007 was originally designed so that other add-ins registered in HKEY_LOCAL_MACHINE would appear in the user interface and could be disabled by using the COM Add-ins window.

After installing the hotfix and enabling it using the EnableLocalMachineVSTO registry key, add-ins developed using VSTO will load. However, by default they will still be displayed in the user interface. These types of add-ins can be optionally hidden in the COM Add-ins window by deploying the DontDisplayHKLMAddins additional registry key. For more information, see:

929590 Known issues when you develop custom solutions for Office Outlook 2007

http://support.microsoft.com/default.aspx?scid=kb;EN-US;929590

The end result is that by deploying both the EnableLocalMachineVSTO and DontDisplayHKLMAddins registry keys, Office 2007 will now revert back to Office 2003 (and earlier) behavior for VSTO-based add-ins. The only difference is that the add-ins will be listed in the new Office 2007 Trust Center. However, users will not be able to remove them because they will not appear in the COM Add-ins window.

Silverlight 4: Out-Of-Browser Enhancements

15.03.2010 12:00:00 | Oliver Scheer

Silverlight 4 comes with a lot of new features. A common request was the support of different types of window styles for the out-of-browser-functionality.

And … Microsoft listen … The support is there. This feature enables a developer to create their on style of window styles for their browser. This is requires, the agreement of the user, to change this.

When you customize your application for deployment, you have now several options in the configuration.

image

The button “Out-of-Browser-Settings” enables the developer to customize the behavior of the Application, when it runs out of browser. If you request elevated trust from the user, you can choose different styles of a window.

image

 

When the user tries to install the application he got the following standard installation Prompt.

image

After that, he can enjoy one of the following window styles:

  • Default Style
  • No Border
  • Single Border
  • Borderless round corners
    Have fun,
    The-Oliver

Daily Demo: Tipping Text

15.03.2010 09:00:00 | Oliver Scheer

Basierend auf einer wahren Begebenheit habe ich das folgende Steuerelement gebastelt. Es macht nichts anderes als Text zu tippen … klingt einfach … ist es auch.

image

Liveversion: hier.

Code für das Steuerelement

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace TheOliver.Controls
{
    public class TippingText : UserControl
    {
        TextBox _textblock;
        DispatcherTimer _timer;

        public TippingText()
        {
            _textblock = new TextBox();

            this.Content = _textblock;

            _timer = new DispatcherTimer();
            
            _timer.Interval = new TimeSpan(0, 0, 0, 0, TippingSpeedInMilliseconds);
            _timer.Tick += (s, e) =>
                {
                    ShowNextCharacter();
                    _currentCharacter++;
                    if (_currentCharacter >= Text.Length)
                    {
                        _timer.Stop();
                        if (Repeat)
                        {
                            _currentCharacter = 0;
                            _timer.Start();
                        }
                    }
                };

            this.Loaded += (s, e) =>
                {
                    if (Text.Length > 0)
                    {
                        _timer.Start();
                    }
                };
        }

        private void ShowNextCharacter()
        {
            if (Text.Length > _currentCharacter + 1)
            {
                _textblock.Text = Text.Substring(0, _currentCharacter + 1);
            }
        }

        private int _currentCharacter;

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                "Text", 
                typeof(string), 
                typeof(TippingText), 
                new PropertyMetadata("No Text", OnValueChanged));

        private static void OnValueChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            TippingText tt = sender as TippingText;
            tt._timer.Stop();
            tt._timer.Interval = new TimeSpan(0, 0, 0, 0, tt.TippingSpeedInMilliseconds);
            tt._currentCharacter = 0;
            tt._textblock.TextWrapping = tt.TextWrapping;
            tt._textblock.TextAlignment = tt.TextAlignment;
            tt._textblock.Text = tt.Text;
            if (tt.Text.Length > 0)
            {
                tt._timer.Start();
            }
        }

        public int TippingSpeedInMilliseconds
        {
            get { return (int)GetValue(TippingSpeedInMillisecondsProperty); }
            set { SetValue(TippingSpeedInMillisecondsProperty, value); }
        }

        public static readonly DependencyProperty TippingSpeedInMillisecondsProperty =
            DependencyProperty.Register(
                "TippingSpeedInMilliseconds", 
                typeof(int), 
                typeof(TippingText),
                new PropertyMetadata(200, OnValueChanged));

        public bool Repeat
        {
            get { return (bool)GetValue(RepeatProperty); }
            set { SetValue(RepeatProperty, value); }
        }

        public static readonly DependencyProperty RepeatProperty =
            DependencyProperty.Register(
                "Repeat", 
                typeof(bool), 
                typeof(TippingText), 
                new PropertyMetadata(true, OnValueChanged));

        public TextWrapping TextWrapping
        {
            get { return (TextWrapping)GetValue(TextWrappingProperty); }
            set { SetValue(TextWrappingProperty, value); }
        }

        public static readonly DependencyProperty TextWrappingProperty =
            DependencyProperty.Register(
                "TextWrapping",
                typeof(TextWrapping), 
                typeof(TippingText),
                new PropertyMetadata(TextWrapping.Wrap, OnValueChanged));

        public TextAlignment TextAlignment
        {
            get { return (TextAlignment)GetValue(TextAlignmentProperty); }
            set { SetValue(TextAlignmentProperty, value); }
        }

        public static readonly DependencyProperty TextAlignmentProperty =
            DependencyProperty.Register(
                "TextAlignment", 
                typeof(TextAlignment), 
                typeof(TippingText), 
                new PropertyMetadata(TextAlignment.Center, OnValueChanged));

        
    }
}

Download Sourcecode

Wie böse ist RAD?

15.03.2010 07:42:00 | Jürgen Gutsch

Jeder der mich kennt, weiß, dass ich keine Freund von RAD-Controls (Rapid Application Developement) – besonders von Controls und Tools diverser Drittanbietern – bin.

Aber halte ich RAD deshalb generell böse?

Ralf Westphal schreib im aktuellen Beitrag seiner Kolumne “Sandbox” (in der dotnetpro 4/2010) sinngemäß und zusammengefasst: RAD-Tools für sich gesehen sind nicht böse, sondern die naive Herangehensweise, also zu glauben, dass RAD alle Probleme erledigt, ist böse, bzw. schlecht und die daraus resultierenden Probleme werfen ein schlechtes Licht auf RAD.

Ist das wirklich so?

Generell kann ich die Frage leider nicht komplett beantworten. Sondern nur aus meiner Sicht als Webentwickler, auf RAD-Tools und RAD-Controls für ASP.NET. Ich kann mich also nur auf ASP.NET beziehen und weis nicht wie es sich bei WinForms, WPF und SilverLight verhält.

So wie Ralf es beschreibt, würde ich generell erst mal “Ja” sagen, aber aus meiner Sicht kommen einige Fragen hinzu. Warum gibt es denn überhaupt die Möglichkeit, dass man sich bei naiver Herangehensweise seine komplette Anwendung mit RAD-Tools und RAD-Controls versauen kann? Warum schaffen es die Anbieter nicht, einfache, kleine und flexible Tools zu schaffen mit denen man nicht viel falsch machen kann? Warum müssen alle möglichen, erdenkbaren Funktionen von Anfang an in einem RAD-Tool, bzw. RAD-Control enthalten sein?

Schöne und positive Beispiele kommen von Microsoft selber: LINQ to SQL; die ASP.NET Controls GridView und Calendar sind absolut flexibel beliebig erweiterbar. Es ist also generell machbar.

Zu großer Umfang

Müssen RAD-Tools und drittanbieter-Controls so viele Funktionen anbieten, das der naive Nutzer alle Möglichkeiten ausnutzen will? Anbieter von RAD-Tools wollen die breite Masse zufrieden stellen und stellen deshalb die eierlegende Wollmilchsau zur Verfügung. Das muss aber nicht sein, ganz im Gegenteil. Ich persönlich nutze lieber die kleine Schlanke Komponente die ich selber erweitern kann und nicht das Universal-Tool von dem ich 80% nicht benötige, aber mit schleifen muss.

Unförmiger HTML Code

Wer meinen UG-Vortrag im Herbst (beim .NET-Stammtisch Konstanz-Kreuzlingen) gesehen hat, konnte miterleben wie sich die verschiedenen Hersteller bei der Menge an HTML-Code, JavaScripts und HTML-Verschachtelungen überboten haben. (Ich bin gerne bereit diesen Vortrag auch in einer anderen UGs zu halten. Machen Sie sich dabei auf was gefasst *fg*)

Ein namhafter Hersteller von RAD-Controls zwingt die Browser in die Knie, wenn man mehr als 10 abhängige Comboboxen nutzt, die unter anderem Grids beinhalten. Eine Combobox dieses Anbieters benötigt für 10 Listeneinträge übrigens mehrere ineinander verschachtelte HTML-Tabellen und mehr als 30 Zeilen HTML-Code. Nutzt man zusätzlich noch die Möglichkeit, beim Aufklappen der Combobox ein Grid anzuzeigen, erhöht sich die Menge des benötigten HTML-Codes um die benötigte Menge des Grids, welches auch nicht gerade sparsam mit verschachtelten HTML-Tabellen umgeht. Hinzu kommen Unmengen von JavaScripts, die direkt auf der Seite ausgegeben werden. Die kleine Combobox entpuppt sich bei genauerer Betrachtung als ein riesiges, unperformates und überladenes Control.

Ein weiterer Hersteller hatte es übrigens nicht geschafft, trotz enormer Mengen an unsauberen Code und JavaScripts, die Combobox in allen Browsern zu funktionieren: Im Opera war lediglich eine leere Standard-Combobox zu sehen.

Zu unflexibel und schlecht erweiterbar

Warum schaffen es die meisten Hersteller von RAD-Tools und drittanbieter-Controls nicht, flexible und erweiterbare Tools und Controls zu erstellen?

In einer Kalender-Komponente eines weiteren namhaften Herstellers, benötigte ich zwei Wochen, um ein Doppelklick-Event auf einen Kalendertag abzufangen und einen eigenen Termindialog anzubinden.

  • Warum ich nicht den vorhandenen Dialog genutzt habe?
    Dieser Passte nicht zu der Art von Terminen war nur schwer erweiterbar und passte nicht in das Layout.
  • Warum ich nicht die Komponente eines anderen Herstellers genommen habe?
    Alle anderen waren aufgrund von unsauberen HTML-Code einfach zu unperformant beim Aufbau der Seite, zudem schaffte es das herstellereigene JavaScript nicht mal mehr die per Callback geholten Termine in diesen unmöglichen Code zu setzen.

Grund hier war eine nicht dokumentierte, clientseitige JavaScript API und das tagelange JavaScript-Debugging in unschönem Code.

Fazit

Es ist nicht nur alleine die Naivität der, Nutzer sondern auch die Art wie die Hersteller die Controls produzieren und vermarkten. Auf den Demoseiten der Hersteller sieht alles toll und bunt aus, alles funktioniert einwandfrei, aber dort habe ich auch nie mehr als zehn abhängige Grid-Comboboxen gesehen ;-)

Man RAD-Controls ist man unheimlich schnell bei der Entwicklung von schönen, bunten und benutzerfreundlichen Oberflächen.

Mit RAD-Controls stößt man aber auch unheimlich schnell auf Probleme, wenn man spezielle Anforderungen hat und wenn man Anpassungen und Erweiterungen an den Controls vornehmen möchte. RAD-Controls werden als schnell einsetzbare Tools präsenteiert, aber unter den schönen bunten Oberfläche erweisen sich die meisten als unflexibel, schlecht dokumentiert und unperformant.

Klingt jetzt wahnsinnig abwertend, gell?

Aber ich möchte RAD-Controls nicht generell schlecht machen. Wenn man keine sehr speziellen Anforderungen an z. B: Grid und Kalender-Controls hat, kann und sollte man diese auch nutzen. Der Entwicklungsaufwand um selber eine entsprechendes Control zu schreiben ist einfach zu hoch.

Nur warum sollte man eine TextBox, eine ComboBox, eine CheckBox, etc. von einem Drittanbieter verwenden? Wegen dem schönen Design? Wohl kaum, denn dafür gibt es CSS.

Wegen einer speziellen Funktion mehr? Eine Funktion ist schnell selber geschrieben. Oder man benutzt vorhandene JavaScript-Frameworks, wie z. B. jQuery, um Controls zu erweitern ohne den HTML-Code aufzublähen und die Browser in die Knie zu zwingen.

Im Gegenteil halte ich RAD für absolut Sinnvoll und sollte auf alle Fälle in Betracht gezogen werden, wenn es darum geht den Aufwand klein zu halten. Allerdings hat Ralf absolut recht, wenn man die meisten, heute auf dem Markt befindlichen RAD-Tools anschaut, sollte, bzw. darf man nicht naiv daherkommen und einfach so alle möglichen Tools einsetzen und nutzen, sondern sollte sich penibel mit den Tools auseinandersetzen, abwägen und schauen wie erweiterbar und flexibel die Controls und Tools wirklich sind.

Zu guter Letzt:

Ich kann es einfach nicht lassen und muss hier mal ein anonymisiertes Beispiel posten.

Es soll ein schöner, bunter, formatierter Button angezeigt werden:

<table cellpadding="0" cellspacing="0" style="height: 57px;">
  <tr>
    <td>
      <table cellspacing="0" cellpadding="0" id="ctl00_phContent_BackgroundImageTextGroupBox_Button1" border="0" style="height:30px;width:90px;border-collapse:collapse;border-collapse:separate;">
        <tr>
          <td id="ctl00_phContent_BackgroundImageTextGroupBox_Button1_B" align="center" style="color:White;background-image:url(Images/Wine/normal.jpg);cursor:pointer;padding-bottom:2px;">
            <div id="ctl00_phContent_BackgroundImageTextGroupBox_Button1_CD" class="dxb">
              <span>Submit</span>
            </div>
          </td>
          <td style="width:0%;">
            <input value="" onfocus="ButtonGotFocus('ctl00_phContent_BackgroundImageTextGroupBox_Button1')" name="ctl00$phContent$BackgroundImageTextGroupBox$Button1" type="submit" style="background-color:Transparent;border-width:0px;height:0px;width:0px;padding:0px;" />
          </td>
        </tr>
      </table>
<script id="dxss_202605327" type="text/javascript">
<!--
addHoverItems('ctl00_phContent_BackgroundImageTextGroupBox_Button1',[[[''],['padding-bottom:2px;color:#FAD9E0;background-image:url(Images/Wine/hover.jpg);'],['B'],['','TC'],[['']],['Img']]]);
addPressedItems('ctl00_phContent_BackgroundImageTextGroupBox_Button1',[[[''],['padding-bottom:2px;color:#DCB7C8;background-image:url(Images/Wine/pressed.jpg);'],['B'],['','TC'],[['']],['Img']]]);
var o = new ClientButton('ctl00_phContent_BackgroundImageTextGroupBox_Button1');
window['ctl00_phContent_BackgroundImageTextGroupBox_Button1'] = o;
o.uniqueID = 'ctl00$phContent$BackgroundImageTextGroupBox$Button1';
addSelectedItems('ctl00_phContent_BackgroundImageTextGroupBox_Button1',[[['bf'],[''],['CD']]]);
o.InlineInitialize();
//-->
</script>
    </td>
  </tr>
</table>

Die “alternative” mit normalem HTML würde so aussehen:

<input type="submit" value="Submit" class="beautifulButton" id="submitButton" runat="server" />

Formatiert mit CSS und ggf. erweitert per jQuery und man hat ein besseres Ergebnis, da der HTML-Code schlanker ist und die Browser weniger zeit für die Verarbeitung benötigen.

DotNetKicks-DE Image

Design.Toolbox – Portal für Online Design Trainings

15.03.2010 01:00:00 | Oliver Scheer

Microsoft hat gerade eine neue Plattform für kostenfreie Online-Trainings zu Silverlight und Expression Studio gelauchnt. Zielgruppe sind alle Designer und Design-affine Entwickler.

image

Link: http://www.microsoft.com/design/toolbox/

Twitter Weekly Updates – 2010-03-14

14.03.2010 23:59:00 | Mario Priebe

Formula One Livestream outside from Germany, Austria, Switzerland use http://goo.gl/8afE # Formula One livestream [german] http://goo.gl/U8oT # RT @thecodeproject: Globalization in WPF or Silverlight: Dynamic globalization without breaking design time. http://bit.ly/akzVbP # thx for sharing RT @edward_tanguay: english learners: this text-to-speech service is best I've heard http://is.gd/apMWf # share documents, pics and files over your #twitter account

Twitter Weekly Updates – 2010-03-14

14.03.2010 23:59:00 | Mario Priebe

Formula One Livestream outside from Germany, Austria, Switzerland use http://goo.gl/8afE # Formula One livestream [german] http://goo.gl/U8oT # RT @thecodeproject: Globalization in WPF or Silverlight: Dynamic globalization without breaking design time. http://bit.ly/akzVbP # thx for sharing RT @edward_tanguay: english learners: this text-to-speech service is best I've heard http://is.gd/apMWf # share documents, pics and files over your #twitter account

Twitter Weekly Updates – 2010-03-14

14.03.2010 23:59:00 | Mario Priebe

Formula One Livestream outside from Germany, Austria, Switzerland use http://goo.gl/8afE # Formula One livestream [german] http://goo.gl/U8oT # RT @thecodeproject: Globalization in WPF or Silverlight: Dynamic globalization without breaking design time. http://bit.ly/akzVbP # thx for sharing RT @edward_tanguay: english learners: this text-to-speech service is best I've heard http://is.gd/apMWf # share documents, pics and files over your #twitter account

(Spreu + Weizen).Select(Programmierer)

14.03.2010 12:41:36 | Christina Hirth

Obwohl wir Jeff Atwood schon vor Monaten von unseren Bloggerliste gestrichen haben, ich habe ihn noch nicht aus meinem Googlereader entfernt. Er ist ein Typ, der liebt viel Wirbel zu verursachen (Scott Hanselmann nennt ihn aus den Wörtern friend und enemy “my friendemy” ) aber manchmal trifft er den Nagel auf den Kopf. [...]

Hyperlinks in das Word-Nirvana

14.03.2010 01:16:00 | Jan Christian Selke

Das Kopieren von Dokumentinhalten von einem Dokument in das Andere ist ein weites und interessantes Thema im Kontext Word2007/2010 und OpenXml SDK. Hierbei können verschiedenste Abhängigkeiten eine große Rolle spielen. Werden beispielsweise Hyperlink beinhaltende Dokumentteilte kopiert, ist die Überraschung groß. Der Link verweist unter Umständen nicht nur ins Nirvana, er ist selbst vollständig dorthin gewandert. Warum das so ist und was man dagegen machen kann, möchte ich am Beispiel des Kopierens von Inhalten aus einem MainDocument zeigen.

Hyperlinks werden als eigenständiges Element w:hyperlink zwischen Paragraphen w:p und Runs w:r abgelegt. Alternativ zum w:p kann als parent Element auch häufig ein w:sdtContent, ein ContentControl, vorliegen.

Hyplerlink

Das wichtigste Attribut eines Hyperlinks ist das Attribut r:id. Dieses verweist auf eine externe Beziehung, die in dem Dokument document.xml.rels in dem Unterordner _rels innerhalb der Package Struktur hinterlegt wird.

ordner

Bei dem Attribut w:history handelt es sich um einen OnOffValue, im Prinzip einen Boolschen-Wert, durch den angezeigt wird, ob diesem Link bereits gefolgt wurde.

Öffne ich nun dasDokument document.xml.rels finde ich unter der ID 4 den folgenden Eintrag.

<Relationship
    Id="rId4"
   
Type=”
http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink”
    Target=”
http://jcselke.blogspot.com“
    TargetMode="External" />

Damit ist auch schon geklärt, weshalb Hyperlinks verschwinden. Sie werden also als Externe Beziehung abgelegt, in der die Ziel URL des Hyperlinks hinterlegt ist. Diese werden natürlich nicht durch einfaches Kopieren von Inhalten aus dem Dokument übernommen und gehen daher verloren.

Gut, das bloße Kopieren der Inhalte reicht also nicht aus. Was kann aber getan werden? Eine Lösung kann es sein, durch alle HyperlinkRelationships des Mainparts zu iterieren und diese Stück für Stück in das Zieldokument zu übertragen. Dazu werden Ausgangs- und Zieldokument geöffnet und die Inhalte, in diesem Fall durch Zuweisen des InnerXml, kopiert.

public void ImportContent()
{
using (var package = WordprocessingDocument.Open("c:\\test\\hyperlink.docx", true))
{
var mainDocumentPartSource = package.MainDocumentPart;
var documentSource = mainDocumentPartSource.Document;
using (var packageTarget = WordprocessingDocument.Open("c:\\test\\hyperlink_target.docx", true))
{
var mainDocumentPartTarget = packageTarget.MainDocumentPart;
mainDocumentPartTarget.Document.InnerXml = documentSource.InnerXml;
this.TransferHyperlinks(mainDocumentPartSource, mainDocumentPartTarget);
mainDocumentPartTarget.Document.Save();
}
}
}


Im Anschluss wird in der Methode TransferHyperlinks() eine neue HyperlinkRelationship erzeugt und die alten Werte des zu kopierenden Hyperlinks werden übernommen. Dann wird im Zieldokument das Hyperlink anhand der bisherigen Id identifiziert und die alte Id durch die der neuen HyperlinkRelationship ersetzt.



private void TransferHyperlinks(OpenXmlPartContainer openXmlPartContainer, MainDocumentPart mainDocumentPartTarget)
{
foreach (var hyperlinkRel in openXmlPartContainer.HyperlinkRelationships)
{
var newHyperLinkRel = mainDocumentPartTarget.AddHyperlinkRelationship(hyperlinkRel.Uri, hyperlinkRel.IsExternal);
var relationship = hyperlinkRel;
var importedHyperlink = mainDocumentPartTarget
.Document.Descendants<Hyperlink>()
.Where(x => x.Id == relationship.Id).First();
importedHyperlink.Id = newHyperLinkRel.Id;
}
}


So lässt sich natürlich auch mit allen anderen Parts verfahren, die Hyperlinks enthalten können. Da wären vor allem aber nicht ausschließlich Header- und FooterParts zu nennen.

Wie verwende ich den Meta-Tag robots in meinem Blog?

13.03.2010 18:44:38 | Klaus Bock

Suchmaschinenrobot

Bewusst, dynamisch und abhängig von der gerade aufgerufenen Seite. Aber dazu später mehr.
Der Meta-Tag robots ist eines der wertvollsten Werkzeuge im Umgang mit Suchmaschinen, wird aber oft, gerade in der deutschen .NET Blogosphäre, sträflich vernachlässigt. Die meisten Blogs verwenden den robots-Tag mit den Werten index, follow in jeder Seite ihres Blog. Viele Blogs verwenden den Tag gar nicht, was den vorherigen Werten gleich kommt. Manches Blog, ich will hier keine Namen nennen, verwendet den Tag gleich mehrfach in einer Seite, erst mit noindex, nofollow und drei Zeilen weiter mit index, follow.
Wie man an diesen Beispielen bereits sehen kann, machen sich die wenigsten Blogbetreiber Gedanken darüber, wie eine Suchmaschine mit dem Inhalt des Blog umgehen soll. Frei nach dem Motto: Google, Yahoo, Bing und wie sie nicht alle heißen, werden es schon richten.
Das tun sie auch, aber bestimmt anders als der Blogbetreiber vielleicht will.

Was macht so ein Spider, oder auch Crawler genannt, mit unseren Blogs?
Er ist hungrig nach Futter und seine Lieblingsspeise ist nun mal Text. Der erste Kontakt mit einem Blog ist meist die Startseite. Hier sind in typischer Manier die letzten Artikel, entweder als Teaser oder manchmal als kompletter Artikel, aufgeführt. Für den Crawler ist das schon eine ganze Menge. Ein hat mehrere Überschriften mit H1 oder H2 Tags und einiges an zugehörigem Text. Wenn sich jetzt im Teaser unter der jeweiligen Überschrift einige Wörter aus eben dieser Überschrift wiederfinden, ist der Crawler schon glücklich. Wird in der Startseite auch noch der robots-Tag mir index, follow verwendet, hat er was er will. Die Startseite landet im Index.
Bei Webseiten, die oftmals sehr viel Wert auf die Startseite legen, mag dieses Verhalten ja gewünscht sein. Ich spreche hier aber von einem Blog. Ich will nicht meine Startseite im Index einer Suchmaschine sehen, sondern meine Artikel.
Nehmen wir an, der Crawler folgt von der Startseite aus dem Link zum Artikel. Er analysiert diesen Artikel und stellt fest, dass Teile des Inhalts bereits im Index vorhanden sind. Was soll ihn nun dazu bewegen diese Artikelseite ebenfalls in den Index mit aufzunehmen? Er hat doch bereits auf der Startseite gefunden was er wollte.

Nun gut, dieses Szenario ist wahrscheinlich stark überzeichnet. In Wirklichkeit sind noch ganz andere Faktoren von Bedeutung. Welche genau weiß ich nicht, denn ich bin kein SEO-Fachmann. Nichtsdestotrotz sagt mir der gesunde Menschenverstand, dass der oben geschilderte Fall sich ziemlich sicher so verhält. Was also tun?

Kurz und knapp, ein radikaler Schnitt. Alle Übersichtsseiten, dazu gehört auch die Startseite, werden mit den Werten noindex, follow im Meta-Tag robots versehen. Klingt schmerzhaft? Ist es für den Moment auch.
Ich habe mich vor ca. drei Monaten getraut diesen Schritt zu tun. Anfangs fiel die Anzahl der indizierten Seiten meines Blog ins Bodenlose. Aber nach und nach zeigte sich der gewünschte Effekt. Mittlerweile sind die verschiedenen Artikel im Index und ranken auf den vorderen Plätzen in den SERPs.
Bei einer Suche zu den Begriffen shared memory .net in Google wird mein Blog auf der ersten Seite gelistet. Wenn diese Suche auf Seiten aus Deutschland begrenzt wird, werden sogar zwei Artikel meines Blog auf der ersten Seite gelistet. Die gleiche Suche bei Bing, listet mich auf die beiden ersten Plätze. Auch mit dem Begriff Web Slice wird mein Blog sowohl bei Google als auch bei Bing auf der ersten Seite gelistet; und das bei 13 Millionen Ergebnissen bei Bing und über 15 Millionen bei Google. Ich bin mit diesem Ergebnis mehr als zufrieden.

Programmtechnisch ist die dynamische Verwendung des robots-Tag nicht schwer umzusetzen.
Da BlogEngine.NET nur einen ContentPlaceHolder in der MasterPage des jeweiligen Theme verwendet, ist der Weg über den Head-Bereich im Markup verbaut. Eine rein codebasierende Variante ist allerdings auch nicht schwerer zu verwirklichen.
Da auf die einzelnen Meta-Tags im Header über einen ControlCollection zugegriffen werden kann, ist der robots-Tag einfach zu finden. Wenn der Meta-Tag gefunden wurde, wird der entsprechende Wert gesetzt. Sollte er nicht gefunden werden, wird der Tag mit dem entsprechenden Wert der ControlCollection hinzugefügt.
In eine Methode verpackt, muss dieser Methode nur noch der gewünschte Wert mitgegeben werden. Um Code-Redundanz zu vermeiden, wird die Methode als statische Methode in einer Hilfsklasse verwendet, der als zweiter Parameter die aktuelle Page-Instanz mitgegeben wird.

public static void AddMetaRobots(string metaContent, Page page)
{
    HtmlMeta tag = null;

    foreach (Control ctrl in page.Header.Controls)
    {
        if (ctrl is HtmlMeta
            && ((HtmlMeta)ctrl).Name.ToLowerInvariant() == "robots")
        {
            tag = (HtmlMeta)ctrl;
            tag.Content = metaContent;
            break;
        }
    }

    if (tag == null)
    {
        var meta = new HtmlMeta();
        meta.Name = "robots";
        meta.Content = metaContent;

        page.Header.Controls.Add(meta);
    }
}

So kann nun einfach in jeder Seite des Blog der richtige Wert für den robots-Tag gesetzt werden. In der Startseite, dem Archiv, im Web Slice Container und der Übersichtsseite für Artikelserien wird der Wert noindex, follow gesetzt. Im Page_Load Ereignis der jeweiligen Seite braucht nur ein Aufruf der obigen Methode zu erfolgen:

BlogUtils.AddMetaRobots("noindex, follow", this.Page);

In den Artikel- und statischen Seiten wird dementsprechend index, follow gesetzt.

BlogUtils.AddMetaRobots("index, follow", base.Page);

Fazit:

Wenn mir als Blogbetreiber von den einschlägigen Suchmaschinen ein Werkzeug zur Steuerung der Suchmaschinenbots zur Verfügung gestellt wird, warum sollte ich es dann nicht nutzen?
In der heutigen Zeit, mit über 180 Millionen Seiten im Internet, ist die Auswahl an Informationen nahezu unüberschaubar. Die Anzahl der SERPs jeder Suchanfrage steigen ständig. Wie soll unter diesen Voraussetzungen ein Artikel meines Blog überhaupt gefunden werden? Wenn ich nichts dafür tue, mit Sicherheit gar nicht.

Technorati-Tags: asp.net | blogengine.net | meta-tag | robots

Git, Mercurial und die PowerShell

13.03.2010 18:41:19 | Albert Weinert

 

Ich versuche seit ein paar Tagen die cmd.exe durch die PowerShell abzulösen. Ist so einiges anders, aber dies ist hier nicht das Thema.

Dabei bin ich auf zwei Skripte für die PowerShell gestoßen mit denen man sich a) den Status eine Git-Repositories als Command-Prompt anzeigen lassen kann, sowie b) git ein wenig Tab-Completion beibringt (Befehle und Repositories).

Ich habe es ein wenig refakttorisiert, zusammengefasst, für mich verbessert und auch noch Mercurial Support eingebaut. Es sind meine erste Schritte in der PowerShell, also hab nachsicht ;).

So schaut es aus.

image

Sofern es in Hg oder Git Repository ist so wird dies in der Titel-Leiste angezeigt, dort ist auch der vollständige Pfad zu sehen, während im Prompt nur der aktuelle Verzeichnisname steht.

Zwischen den Klammern sind dann die Repository Informationen, der Name des aktuellen Branches (in Rot wenn es nicht erfasste Dateien gibt), danach folgen Zahlen die mit +, ~ und - als Vorzeichen. + bedeuten hingefügte Dateien, ~ die geänderten und – gibt die gelöschten Dateien an.

An ein paar Stellen wo bei git und hg die Befehle stehen oder wo Namen von Branches und Remotes gebraucht werden können die mit Tab-Completion durchgetabt werden.

Das ganze ist sicher noch nicht vollständig oder optimal, aber es ist ein Anfang.

Hiermit stelle ich es der Allgemeinheit zu Verfügung und hoffe dass es sich ein wenig weiterentwickelt.

http://github.com/DerAlbertCom/GitHgPowerShell

Um diese zu verwenden einfach die beiden Skripte nach

%USERPROFILE%\My Documents\WindowsPowerShell

kopieren (getestet unter Windows 7). Wenn schon eine profile.ps1 vorhanden ist muss natürlich aufgepasst werden und das ganze Integriert werden.

Viel Spaß damit und forkt fleißig um das ganze zu verbessern ;)

Technorati Tags: git,mercurial,hg,powershell

#9 im Kino

13.03.2010 14:25:09 | Mario Priebe

Das finde ich ja mal eine gute Nachricht. Der damals (2005) schon sehr populäre Kurzfilm 9 von Shane Acker kommt in unsere Kinos. Für diesen Kurzfilm wurde Acker zum Academy Award nominiert. (Ob er ihn auch bekommen hat? Keine Ahnung.) Für alle diejenigen, die den Kurzfilm noch nicht kennen, hier in “voller Länge”. Und hier der Trailer

ObservableCollection myLinks

12.03.2010 16:18:12 | Mario Priebe

Mongo DB ist eine “Open Source” dokumentenorientierte  Datenbank (document oriented database). Das weit verbreiteste DBMS mit einer dokumentenorientierten Datenbank heisst Lotus Notes Einige Links zu MongoDB Offizielle Website http://www.mongodb.org MongoDB Wiki http://en.wikipedia.org/wiki/MongoDB MongoDB for CSharp http://github.com/samus/mongodb-csharp MongoDB for CSharp II http://odetocode.com/Blogs/scott/archive/2009/10/13/experimenting-with-mongodb-from-c.aspx YouTube Video http://www.youtube.com/watch?v=dOP3w-9Q6lU Linq2MongoDB http://www.claassen.net/geek/blog/2009/09/linq2mongodb-building-linq-provider-for.html MongoDB im Dauerstress http://blogs.msdn.com/dparys/archive/2010/03/12/mongodb-im-stress-test.aspx CouchDB vs. MongoDB Benchmark http://www.snailinaturtleneck.com/blog/2009/06/29/couchdb-vs-mongodb-benchmark/ Using MongoDB with Visual Studio http://somewebguy.wordpress.com/2010/02/09/using-mongodb-with-visual-studio/ (Video) Understanding ObjectId in

MongoDb im Stress Test

12.03.2010 14:56:36 | Dariusz Parys

Ich habe mich ein wenig mit MongoDB beschäftigt, ich finde den Ansatz interessant Daten einfach als Binary JSON ablegen zu können. Ich wollte allerdings wissen wie der Einsatz von MongoDB in einer Web Anwendung aussieht. Hierzu habe ich eine ASP.NET MVC Anwendung verwendet die lediglich Daten anzeigt, erzeugt und aktualisert. Dazu erzeuge ich in jedem Request einen Connect und Disconnecte mich wieder im Dispose Event vom Controller. Diese Anwendung habe ich mittels eines Web Tests in Visual Studio...(read more)

Entity Framework 4 Webcast

12.03.2010 13:09:59 | Dariusz Parys

Gestern ist der MSDN Webcast zum Thema Entity Framework 4 – Was ist neu? erschienen. In diesem Webcast gehe ich vor allem auf eine neue Möglichkeit mit dem Entity Framework 4 zu arbeiten ein: Code First. Code First erlaubt es beliebige Objektmodelle auf ein relationales Schema zu mappen, ohne dabei Abhängigkeiten im Objektmodell auf das Entity Framework zu haben. Beispiel Die Klasse Firma hat Mitarbeiter. Diese beiden Klassen liegen in einem eigenen Assembly und könnten so aussehen: public class...(read more)

Neues in WPF 4

12.03.2010 12:10:57 | Mario Priebe

Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen. Im folgenden Artikel möchte ich über einige Neuerungen in WPF 4.0  schreiben Visual

Neuerungen in Visual Studio 2010

12.03.2010 11:48:11 | Mario Priebe

Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen. Im folgenden Artikel möchte ich über einige Neuerungen in Visual Studio 2010

Weitere Neuerungen im .NET Framework 4.0

12.03.2010 11:03:21 | Mario Priebe

Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen. Im folgenden Artikel möchte ich über weitere kleine Neuerungen und Veränderungen im

Parallele Programmierung mit .NET 4.0

12.03.2010 10:35:29 | Mario Priebe

Ich hab kürzlich die BASTA Spring 2010 besucht (über 500 Teilnehmer). Es war wirklich eine sehr informative Veranstaltung über aktuelle Entwicklungen im .NET Bereich. Folgender Abriss soll die Neuerungen im .NET Framework 4.0, Entity Framework 2, VisualStudio 2010, WPF 4 und Silverlight 4, aufzeigen. Im folgenden Artikel möchte ich über das Neue in der parallelen Programmierung

Ich werde nicht schreiben…

12.03.2010 01:40:00 | Jürgen Gutsch

… dass das die RTM des ASP.NET MVC 2.0 für .NET 3.5 und Visual Studio 2008 draußen ist. Das haben andere bereits zur Genüge getan.
(Und wahrscheinlich werden es im Laufe des Tage noch einige mehr tun.)

Hier eine kleine Auswahl:

Alexander Zeitler:
ASP.NET MVC 2 RTM – für .NET Framework 3.5 SP 1 / Visual Studio 2008

Robert Mühsig:
ASP.NET MVC 2 ist RTM (für VS2008)

Scott Guthrie:
ASP.NET MVC 2 Released

Scott Hanselmann:
ASP.NET MVC 2 Released

Phil Haak:
ASP.NET MVC 2 Released!

Shiju Varghese:
ASP.NET MVC 2 RTM Released !

ASP.NET:
http://www.asp.net/mvc/

Außerdem gibt es Unterstützung für die Installation von ASP.NET MVC (per Web Plattform Installer), Anleitungen zur Migration von Version 1 nach Version 2. Die aktuellen Sourcen sind ebenfalls verfügbar unter codeplex.com (siehe obige Links)

DotNetKicks-DE Image

ASP.NET MVC 2 ist RTM (für VS2008)

12.03.2010 01:33:27 | Robert Mühsig

Das Team rund um Phil Haack hat die RTM Version von ASP.NET MVC 2 fertiggestellt. In den Release Notes finden sich Informationen über Änderungen gegenüber den RCs. Für Leute die eine ASP.NET MVC 1 Applikation haben und migrieren möchten sollten einen Blick auf das Migration Tool vom ASP.NET MVC Team werfen. Momentan ist die RTM nur [...]SHARETHIS.addEntry({ title: "ASP.NET MVC 2 ist RTM (für VS2008)", url: "http://code-inside.de/blog/2010/03/12/asp-net-mvc-2-ist-rtm-fr-vs2008/" });

ASP.NET Webforms Anwendungen und Ajax (Teil 6) kleine Tipps die das Leben leichter machen.

11.03.2010 22:44:25 | Andre Kraemer

In den letzten 5 Einträgen meines Blogs habe ich über verschiedene Möglichkeiten geschrieben Ajax in einer ASP.NET Webforms zu implementieren.

Angefangen mit dem manuellen Weg über das XmlHttpRequest Objekt ging es weiter zu Client Callbacks, dem Updatepanel, dem ASP.NET Ajax Framework sowie jQuery.

Der Fokus meiner Beiträge lag darauf nicht nur einfach zu zeigen welche Möglichkeiten es gibt, sondern zusätzlich auch zu zeigen, welche Datenmengen über die Leitung gehen und ob bzw. welche Teile des ASP.NET Page Life Cycles durchlaufen werden.

Ich hoffe dass ich bei dem ein oder anderen Leser für manchen Aha Effekt sorgen konnte. Zumindest ging es mir persönlich bei der ersten detaillierten Auseinandersetzung mit dem Thema so. Schließlich ist man als ASP.NET Webforms Entwickler traditionell doch eher auf dem Server zu Hause und realisiert vorerst garnicht welchen Overhead Client Callbacks oder das Updatepanel mit sich bringen.

Mein persönliches Fazit ist, dass Updatepanel und Client Callbacks korrekt eingesetzt in einigen Fällen vielleicht berechtigte Alternativen sind, in den meisten Fällen jedoch zum Ajax Framework oder jQuery gegriffen werden sollte.

Meine zurzeit favorisierte Lösung ist - ähnlich wie bei vielen anderen sicherlich auch - der Einsatz von jQuery.

Da mein letztes Beispiel noch ein wenig aufgebläht war, möchte ich an dieser Stelle zwei kurze Tipps geben, die die Arbeit mit jQuery und Ajax ein wenig erleichtern.

Der erste Punkt beschäftigt sich mit der großen Redundanz zwischen den verschiedenen Ajax Aufrufen:

$("#StaticFileLink").click(function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: "Teil5.aspx/ReadStaticFile",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            $("#content").html(msg.d);
        }
    });
});

$("#HelloWorldLink").click(function(e) {
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: "AjaxDemoService.asmx/HelloWorld",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            $("#content").html(msg.d);
        }
    });
});

$("#EchoLink").click(function(e) {
    e.preventDefault();
    var number = $("#EchoTextBox").val();
    var jsonData = "{ 'number' : '" + number + "'}";
    $.ajax({
        type: "POST",
        url: "AjaxDemoService.asmx/Echo",
        data: jsonData,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            $("#content").html(msg.d);
        }
    });
});

Bereits beim ersten Blick auf den Quellcode fällt auf, dass die Werte einiger Parameter statisch zu sein scheinen. So haben folgende Parameter stets einen fixen Wert:

  • type
  • contentType
  • dataType

Außerdem ist zumindest in den ersten beiden Aufrufen auch der Eintrag für data gleich.

Ein Weg um diese Redundanz herum zu kommen wäre eine eigene Funktion, die nur die Variablen Parameter entgegen nimmt.

Standardwerte setzen

Eine andere Alternative besteht darin, Standardwerte für jQuery Ajax Aufrufe zu setzen. Dies sähe dann so aus:

<script type="text/javascript">
    $(document).ready(function() {
        $.ajaxSetup({
            type: "POST",
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        });
        $("#StaticFileLink").click(function(e) {
            e.preventDefault();
            $.ajax({
                url: "Teil6.aspx/ReadStaticFile",
                success: function(msg) {
                    $("#content").html(msg.d);
                }
            });
        });

        $("#HelloWorldLink").click(function(e) {
            e.preventDefault();
            $.ajax({
                url: "AjaxDemoService.asmx/HelloWorld",
                success: function(msg) {
                    $("#content").html(msg.d);
                }
            });
        });

        $("#EchoLink").click(function(e) {
            e.preventDefault();
            var number = $("#EchoTextBox").val();
            var jsonData = "{ 'number' : '" + number + "'}";
            $.ajax({
                url: "AjaxDemoService.asmx/Echo",
                data: jsonData,
                success: function(msg) {
                    $("#content").html(msg.d);
                }
            });
        });
    });
</script>

Neu hinzugekommen sind die Zeilen 2 - 8. Diese setzen Standardwerte für alle folgenden Ajax Aufrufe. Diese Variante kann einiges an Code sparen, ist allerdings mit Vorsicht zu genießen. Sollte nämlich zum Beispiel ein jQuery Plug-In auf der Seite genutzt werden, dass auch die $.ajax Funktion nutzt, könnte es zu Seiteneffekten kommen. Konkret wäre dies der Fall, wenn einer der per .ajaxSetup gesetzten Parameter nicht überschrieben, aber mit einem anderen Wert erwartet wäre. Typischerweise würde dies für den contentType oder oder dataType geschehen.

Serialisieren - einfach gemacht

Eine weitere Unschönheit des gezeigten Quellcodes besteht darin, dass die String Variante des in JSON notierten Objekts data von Hand zusammen gebaut wurde. Dies ist natürlich nicht sonderlich schick. Abhilfe schafft die Funktion stringify des Objekts JSON. Einige Browser wie Firefox ab Version 3.5 oder IE ab der Version 8 haben bereits ein eingebautes Objekt JSON. Für alle anderen gibt es unter http://www.json.org/js.html eine JavaScript Library zum Download, die entsprechenden Support nachrüstet, falls noch nicht vorhanden.

Konkret sähe dies dann wie folgt aus:

<scripthttp://feedproxy.google.com src="scripts/json2.js" type="text/javascript"></script>

[ ... ]


$("#EchoLink").click(function(e) {
    e.preventDefault();
    var number = $("#EchoTextBox").val();
    var jsonData = { 'number': number };
    var jsonString = JSON.stringify(jsonData);
    $.ajax({
        url: "AjaxDemoService.asmx/Echo",
        data: jsonString,
        success: function(msg) {
            $("#content").html(msg.d);
        }
    });

Wie man sieht, wird nun in Zeile 9 zuerst ein JavaScript Objekt jsonData in JSON Notation erzeugt. Dies wird anschließend über JSON.stringify in Zeile 10 in einen String konvertiert. Bei diesem konkreten Beispiel mag der Vorteil noch nicht auf der Hand liegen, spätestens bei komplexen Objekten lernt man die Funktion stringify jedoch schnell zu schätzen.

Bei der Recherche zu den Beiträgen dieser Serie bin ich übrigens auf einen sehr gut geschriebenen Eintrag von Roberto Bez gestolpert. Roberto stellt in seinem Blog Post die verschiedenen Varianten kompakt gegenüber. Die Lektüre des Artikels kann ich jedem Ajax interessierten Webforms Entwickler wärmstens empfehlen.

Weiter hat René Drescher-Hackel in einem Kommentar zu meinem letzen Beitrag, dass mit Ajax.NET Professional (AJAX.PRO) eine weitere effiziente Alternative zur Verfügung steht. Ich muss gestehen, dass mir die Existenz dieses Frameworks bis jetzt vollkommen entgangen ist. Gelobe allerdings Besserung und werde es mir gerne ansehen und mein Beispiel damit umsetzen.



blog.codemurai.de © André Krämer |Impressum | Abonieren

Vorsicht mit Visible = false

11.03.2010 20:41:16 | Andre Kraemer

Eigentlich altbekannt, trotzdem bin ich gerade mal wieder darauf hereingefallen und schreibe des deshalb hier auf:

Ich wollte in einer ASP.NET Webforms Anwendung ein Servercontrol serverseitig über

meinControl.Visible = false;

ausblenden, um es nach einer Nutzeraktion auf dem Client wieder einzublenden:

$(Id$="MeinControl").show();

Leider funktioniert das allerdings nicht, da ein serverseitiges Visible = false dafür sorgte, dass das Control erst garnicht gerendert wurde und somit auf dem Client nicht verfügbar war.

Die simple Lösung im Codebehind:

meinControl.Style.Add(HtmlTextWriterStyle.Display, "none");

Dann klappts auch mit dem Einblenden ;-)

War dieser Beitrag hilfreich? Dann kick ihn doch bitte.



blog.codemurai.de © André Krämer |Impressum | Abonieren
Das Team | Regeln | Impressum
Aktuelle Beiträge aus dem dotnet-forum.de
style="display: none">