Hallo,
ich habe ein Problem und hoffe jemand kann mir helfen.
Ich habe eine C# Anwendung. Dort habe ich eine SpellCheckTextBox die die Rechtschreibung kontrolliert. Wenn ich das Programm so aus dem Visual Studio starte funktioniert dies auch hervorragend. Veröffentliche ich aber die Anwendung mit ClickOnce, so habe ich keine Rechtschreibprüfung mehr.
Kennt jemand das Problem??
Würde mich freuen wenn mir jemand helfen kann, denn bin schon echt am verzweifeln.
Besten Dank und schöne Grüße
Mary
Moin,
meines Wissens wird bei der Rechtschreibprüfung auf die Wörterbücher von Word zurückgegriffen, möglicherweise ist auf dem Client kein Word installiert.
Grüße
Christian
Wo genau kommt die SpellCheckTextBox her?
Eigene Entwicklung? Fremdhersteller? WPF oder Winforms?
Hi chriscolm,
ich habe die Anwendung auch bei mir auf dem PC installiert und ich habe Word. Ich habe sogar unter Veröffentlichen/Erforderliche Komponenten den Punkt "Microsoft Office 2007 Primary Interop Assemliles" hinzugefügt, aber es funzt immer noch nicht.
Gruß
Mary
Hi dN!3L,
die SpellCheckTextBox habe ich als fertige Komponente implemintiert. Windowsform.
Die Anwendung wird über zwei Wege gestreut. Einmal über Citrix/Terminalverbindung und einmal über ClickOnce. Die Terminalversion funktioniert ohne Probleme.
Gruß
Mary
die SpellCheckTextBox habe ich als fertige Komponente implemintiert. Windowsform.
Und wie genau? Denn da es ja keine Standardkomponente ist, können wir ja nur raten, warum die nicht funktionieren sollte.
Du verwendest also die Word-API zum prüfen der Rechtschreibung!? In einer selbst geschriebenen Komponente? Oder wie (meine Glaskugel ist gerade kaputt)?
Hallo,
ich habe in meinem Projekt einen Ordner "Dictionaries" mit den Dateien:
dann habe ich eine Komponente:
namespace Test_Projekt.Komponenten.Allgemein
{
class SpellCheckTextbox : RichTextBox
{
....
public string SpellCheckSprache
{
get {return this.spellCheckSprache;}
set
{
this.spellCheckSprache = value;
spracheSetzen(value);
ausgewaehltesWort = new KeyValuePair<KeyValuePair<int, int>, bool();
spracheGeaendert = true;
}
}
....
public override string Text
{
....
}
private void sprachenBefuellen()
{
sprachen.Clear();
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("DK", new KeyValuePair<string, string>( "Dictionaries//da_DK.dic", "Dictionaries//da_DK.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("DE", new KeyValuePair<string, string>( "Dictionaries//de_DE.dic", "Dictionaries//de_DE.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("ES", new KeyValuePair<string, string>( "Dictionaries//es_ES.dic", "Dictionaries//es_ES.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("FR", new KeyValuePair<string, string>( "Dictionaries//fr_FR.dic", "Dictionaries//fr_FR.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("IT", new KeyValuePair<string, string>( "Dictionaries//it_IT.dic", "Dictionaries//it_IT.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("NL", new KeyValuePair<string, string>( "Dictionaries//nl_NL.dic", "Dictionaries//nl_NL.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("NO", new KeyValuePair<string, string>( "Dictionaries//nn_NO.dic", "Dictionaries//nn_NO.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("FI", new KeyValuePair<string, string>( "", "")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("SE", new KeyValuePair<string, string>( "Dictionaries//sv_SE.dic", "Dictionaries//sv_SE.aff")));
sprachen.Add(new KeyValuePair<string, KeyValuePair<string, string>>("GB", new KeyValuePair<string, string>( "Dictionaries//en_GB.dic", "Dictionaries//en_GB.aff")));
}
private void spracheSetzen(string sprachKuerzel)
{
...
}
private void spracheSetzen(string sprachKuerzel)
{
var spellCheckSprache = sprachen.Find(a => a.Key == sprachKuerzel.ToUpper());
DictFile = spellCheckSprache.Value.Key;
AffFile = spellCheckSprache.Value.Value;
if(!String.IsNullOrEmpty(DictFile) && !String.IsNullOrEmpty(AffFile))
{
woerterBuchGueltig = true;
}
else if(DictFile == null || AffFile == null)
{
throw new NullReferenceException();
}
else if(DictFile == String.Empty || AffFile == String.Empty)
{
woerterBuchGueltig = false;
}
}
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case 15: // this is the WM_PAINT message
// invalidate the TextBox so that it gets refreshed properly
this.Invalidate();
// call the default win32 Paint method for the TextBox first
base.WndProc(ref m);
// now use our code to draw extra stuff over the TextBox
//Spellcheck falls sich die Sprache geändert hat
if(spracheGeaendert)
{
spellCheck();
spracheGeaendert = false;
}
//Zeichnet unseren Zusatz
if(check.Count > 0)
{
using(Graphics graphic = base.CreateGraphics())
{
OnPaint(new System.Windows.Forms.PaintEventArgs(graphic, base.ClientRectangle));
}
}
break;
default:
base.WndProc(ref m);
break;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if(!this.ReadOnly && woerterBuchGueltig)
{
drawSpellCheck(e);
}
}
/// <summary>
/// Markiert die falschen Wörter mit einem Unterstrich
/// </summary>
/// <param name="e"></param>
private void drawSpellCheck(PaintEventArgs e)
{
try
{
if(this.Text.Length > 0)
{
foreach (var wort in check)
{
if (!wort.Value)
{
int charBreite = this.GetPositionFromCharIndex(wort.Key.Value).X -
this.GetPositionFromCharIndex(wort.Key.Value - 1).X;
Point ende = this.GetPositionFromCharIndex(wort.Key.Value);
ende.X += charBreite;
DrawWave(this.GetPositionFromCharIndex(wort.Key.Key), ende, e);
}
}
}
}
catch(Exception)
{
}
}
/// <summary>
/// MouseDown Event für rechte Maustaste und herrausfinden ob das geklickte Wort korrektur bedarf
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if(e.Button == MouseButtons.Right)
{
var location = this.GetCharIndexFromPosition(e.Location);
if(check.Exists(a => a.Key.Key <= location && a.Key.Value >= location) && !check.Find(a => a.Key.Key <= location && a.Key.Value >= location).Value)
{
ausgewaehltesWort = check.Find(a => a.Key.Key <= location && a.Key.Value >= location);
}
else
{
ausgewaehltesWort = new KeyValuePair<KeyValuePair<int, int>, bool>();
}
}
}
/// <summary>
/// Aktualisiert bei Eingabe bestimmter Tasten die Unterstrichelung
/// </summary>
/// <param name="e"></param>
protected override void OnTextChanged(EventArgs e)
{
if(!EventNichtFeuern)
{
base.OnTextChanged(e);
spellCheck();
}
}
/// <summary>
/// Der eigentliche Spellcheck, hier wird jedes Wort geprüft und in check geschrieben mit Anfangs- und Endbuchstaben und ob es falsch oder richtig ist.
/// </summary>
private void spellCheck()
{
if(!this.ReadOnly && woerterBuchGueltig)
{
if(!String.IsNullOrEmpty(this.Text.Trim()))
{
if(!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync(this.Text);
}
}
else
{
Refresh();
}
}
}
/// <summary>
/// Zeichnet die Rotelinie unter den Wörtern
/// </summary>
/// <param name="start">Zeichnen von</param>
/// <param name="end">Zeichnen nach</param>
/// <param name="e"></param>
private void DrawWave(Point start, Point end, PaintEventArgs e)
{
start.Y += this.Font.Height;
end.Y += this.Font.Height;
Pen pen = Pens.Red;
if(end.X > start.X)
{
ArrayList pl = new ArrayList();
for(int i = start.X; i <= (end.X - 2); i += 4)
{
pl.Add(new Point(i, start.Y));
if(i + 2 < end.X)
{
pl.Add(new Point(i + 2, start.Y + 2));
}
}
Point[] p = (Point[])pl.ToArray(typeof(Point));
if(p.Length >= 2)
{
e.Graphics.DrawLines(pen, p);
}
}
}
private void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
if(this.Text != "")
{
contextMenuStrip1.Items.Clear();
if((ausgewaehltesWort.Key.Key != 0 || ausgewaehltesWort.Key.Value != 0) && !this.ReadOnly && woerterBuchGueltig)
{
using(Hunspell hunspell = new Hunspell(AffFile, DictFile))
{
var test = this.Text.Substring(ausgewaehltesWort.Key.Key, ausgewaehltesWort.Key.Value - ausgewaehltesWort.Key.Key + 1);
var suggestions = hunspell.Suggest(test);
if(suggestions.Count > 0)
{
foreach(var vorschlag in suggestions)
{
//Fügt Events zu den Einträgen hinzu
ToolStripMenuItem ts = new ToolStripMenuItem(vorschlag);
ts.Click += new EventHandler(ts_Click);
contextMenuStrip1.Items.Add(ts);
}
//Fügt den Seperator hinzu
ToolStripSeparator tss = new ToolStripSeparator();
contextMenuStrip1.Items.Add(tss);
}
}
}
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItemUndo,
this.toolStripSeparator1,
this.toolStripMenuItemCut,
this.toolStripMenuItemCopy,
this.toolStripMenuItemPaste,
this.toolStripSeparator2,
this.toolStripMenuItemSelectAll});
}
if(this.Text.Length>0)
{
toolStripMenuItemSelectAll.Enabled = true;
}
else
{
toolStripMenuItemSelectAll.Enabled = false;
}
if(this.CanUndo)
{
toolStripMenuItemUndo.Enabled = true;
}
else
{
toolStripMenuItemUndo.Enabled = false;
}
if(this.SelectedText != "")
{
if(!this.ReadOnly)
{
toolStripMenuItemCut.Enabled = true;
}
toolStripMenuItemCopy.Enabled = true;
}
else
{
toolStripMenuItemCut.Enabled = false;
toolStripMenuItemCopy.Enabled = false;
}
}
/// <summary>
/// Event das bei Klick auf eine Korrektur diese statt dem aktuellem Wort einfügt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ts_Click(object sender, EventArgs e)
{
//this.Select(ausgewaehltesWort.Key.Key, ausgewaehltesWort.Key.Value - ausgewaehltesWort.Key.Key+1);
var textaenderung = this.Text.Remove(ausgewaehltesWort.Key.Key, ausgewaehltesWort.Key.Value - ausgewaehltesWort.Key.Key + 1);
this.Text = textaenderung.Insert(ausgewaehltesWort.Key.Key, sender.ToString());
spellCheck();
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
if(!IsDisposed)
{
check.Clear();
using(Hunspell hunspell = new Hunspell(AffFile, DictFile))
{
//Der Regex bestimmt was als ein Wort angesehen wird! Hier werden wir noch für andere Sprachen anpassen müssen
MatchCollection matches = Regex.Matches(e.Argument.ToString(), @"[\w\'\´\`\-\^]+", RegexOptions.Singleline);
foreach(Match match in matches)
{
if(match.Success)
{
KeyValuePair<int, int> wort = new KeyValuePair<int, int>(match.Index, match.Index + match.Length - 1);
var result = new KeyValuePair<KeyValuePair<int, int>, bool>(wort, hunspell.Spell(match.Value));
check.Add(result);
}
}
}
// this.Refresh();
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if(!IsDisposed)
{
if(check.Count > 0)
{
using(Graphics graphic = base.CreateGraphics())
{
OnPaint(new System.Windows.Forms.PaintEventArgs(graphic, base.ClientRectangle));
}
}
Refresh();
}
}
}
}
In der Oberfläche benutze ich dann diese Komponente.
textbox.SpellCheckSprache = datensprache;
Gruß
Mary
Code-Tags hinzugefügt.
Bitte nicht ohne Not solche Massen an Code posten.
Hallo Mary81,
könntest du bitte Code-Tags verwenden und den ganzen Programmcode hättest du auch nicht posten müssen.
ClickOnce kopiert soweit ich weiß immer nur die "relevanten" Files ins Zielverzeichnis. Ich glaube nicht, dass hier deine Dictionaries mitkopiert werden. Evt. musst du die unter Projekteigenschaften\Publish\Application Files noch einbinden oder manuell kopieren.
Lg, XXX
Hi Mary81,
dN!3L hat dir eine ziemlich konkrete Frage gestellt. Warum beantwortest du die Frage einfach nicht und postest statt dessen deinen gesamten, unformatierten Code?
Bitte beachte [Hinweis] Wie poste ich richtig?, Punkt 4c, 4.1, 5, 6 usw.
Christian
Weeks of programming can save you hours of planning
Hi xxxprod,
ich habe versucht den Ordner in den Projekteigenschaften\Publish\Application Files zu kopierten, bring aber leidern nix.
Weist du wie man den einbinden kann?? Bin alle Einstellungen durchgegangen und nichts gefunden.
Danke
Ich hab sowas selber noch nie probiert aber angeblich scheint das mit ClickOnce nicht möglich zu sein: How to include custom data files in ClickOnce deployment?
Aber eventuel hilft dir der Link hier weiter: How to: Include a Data File in a ClickOnce Application
Lg, XXX
Hallo zusammen,
erst mal danke an alle für die Hilfe.
Ich hab es endlich gefunden. In dem Ordner Dictionaries muss man bei jeder Datei folgendes einstellen:
Buildvorgang: Inhalt
In Ausgabeverzeichnis kopieren: Immer kopieren
jetzt funzt es.
Schönes Wochenende an alle
Mary