ich bin gerade dabei eine Simple Chat App zu schreiben und stoße auf folgendes Problem.
Zum darstellen meiner Chat-Nachrichten nutze ich eine ListBox die Anbindung der Daten erfolgt via Binding einer ObservableCollection. Nun möchte ich, wie es für einen Chat üblich ist, das immer zur neusten Nachricht gescrollt wird, was aber nur bei 60% der fälle funktioniert, da so wie ich glaube einfach manchmal das Item im visuellen Baum noch nicht vorhanden ist, aber schon versucht wird zu scrollen. Ich warte auf das Collection Changed event der ObserveableCollection um das Scrollen zu triggern, was wie ich glaube auch der Fehler ist. Ich habe jedoch keine Ahnung wie ich sonst mitbekommen soll wann ein Item der ListBox hinzugefügt wurde.
Hat hier evtl. jemand eine Ahnung wie man das geschickt lösen könnte?
ich reiß mir gerade die Haare aus, ich weiß genau das ich so einen Fehler schonmal beim Pivot hatte aber ich weiß nicht mehr was ich damals gemacht hatte. Jedenfalls will ich einen DataStateBehavior zu meinem UserControl hinzufügen, allerdings bekomm ich während der !ausführung! eine parsing exception (System.Windows.Markup.XamlParseException) dessen position immer auf das letzte "=" des DataStateBehavior zeigt. Auch im XAML Editor wird ein Fehler angezeigt allerdings bei einer Border und das Passt irgendwie alles nicht. Ich hab gerade ein Brett vorm Kopf :-(.
Edit: Ich hab Übersichtshalber mal den VisualStateManager-Block entfernt.
Hat denn echt niemand eine Idee? Ich versteh das echt nicht wenn ich ein neues Projekt anlege mit genau diesem UserControl funktioniert es ohne Probleme..
ich versuche gerade mit biegen und brechen die Items in einem ItemsControl zu animieren wenn sie in Sicht gescrollt werden. Ich habe dazu das ItemsContorl in einen ScrollViewer gepackt und den ManipulationMode auf Control gesetzt damit ich in "echtzeit" an den vertikalen offset komme. Allerdings führt das dazu das der Scroll-Vorgang nicht mehr "schön" (smooth) ist. Daher frage ich mich ob es auch irgendwie anders möglich ist zu erfahren ob ein Item gerade in Sicht gescrollt wird oder nicht.
Hallo, ich frage mich gerade ob es einen Selector für Eigenschaften gibt? Ich würde zb gerne (wie so häufig) den Vordergrund meines Controls an einen Boolschen wert ausrichten möchte aber nicht jedesmal einen ValueConverter schreiben müssen.
Um mal zu verdeutlichen was ich meine hier ein stück code wie die Nutzung aussehen würde/könnte/sollte.
die bilder werden innerhalb des GridContainer via column/row positioniert und gestrecht. der BorderContentContainer.Child property wird die ContentProperty für NinePatch zugewiesen. der BorderContentContainer erhält auch noch ein Margin das von dem .9patch-bild bestimmt wird.
Das NinePatch control sollte sich nun eigentlich anhand der größe des Inhalts vom BorderContentContainer ausrichten das passiert aber nicht. Das Control wird immer unerklärbar groß. Wenn ich jetzt aber anfange MeasureOverride und/oder ArrangeOverride zu nutzen verstehe ich überhaupt nicht mehr was passiert.
Kann mir jemand eventuell helfen zu verstehen wie ich die overrides zu verwenden habe damit die größe des controls sich dem inhalt anpasst?
Ok ich glaube ich bin der unerklärlichen höhe des elements auf die schliche gekommen... das bild Image05 liegt in dem GridContainer auf col 1 row 1 die jeweils mit breite/höhe 1* ausgewiesen sind... was dazu führt das ein 5*7 pixel Image auf 259pixel vergrößert wird... ohne Grund.
das war's...
habe nun die Image elemente durch Border ersetzt und einfach einen ImageBrush als Background verwendet. jetzt wird das element in erwarteter größe dargestellt..
ich versuche mich zu Zeit ein bisschen in WPF verstehe aber gerade nicht so ganz warum mein Element sich so seltsam verhält, bzw. scheine ich nicht richtig zu verstehen wie die DoubleAnimation funktioniert. Was ich erreichen möchte ist, das sich mein element immer wieder von seiner aktuellen Position Richtung Maus auf der Y Achse bewegt. Allerdings scheint das nicht so ganz zu klappen ;) vllt kann mich hier jemand in die richtige Richtung schubsen?
Point s = new Point();
private void Window_MouseMove(object sender, MouseEventArgs e)
{
Point p = e.GetPosition(this);
if (p != s)
{
imgCenter.MoveY(this, p.Y - imgCenter.Height / 2);
}
}
public static void MoveY(this Image target, UIElement rel, double newY)
{
Point p = target.TranslatePoint(new Point(0, 0), rel);
double top = p.Y;
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
DoubleAnimation anim = new DoubleAnimation(top, newY, TimeSpan.FromSeconds(2));
trans.BeginAnimation(TranslateTransform.YProperty, anim);
}
also der stackoverflow tritt wirklich nur innerhalb der framework-methode auf. was soll auch innerhalb der OnClipboardChange()-methode einen stackoverflow verursachen...
diese zeilen:
GetWindowThreadProcessId(GetClipboardOwner(), out pid);
cpid = GetCurrentProcessId();
if (pid != cpid)
OnClipboardChange();
verhindern ja schon das der ausführende prozess OnClipboardChange() aufruft. das problem bleibt weiterhin das einige programme windows dazu bringen WM_DRAWCLIPBOARD zweimal auszuspucken. in einigen artikeln wird beschrieben das die FALSCHE nutzung des clipboards dazu führt aber wenn schon das .NET Framework diesen fehler produziert dann denk ich das es tiefere gründe hat, oder die bei ms kiffen tatsächlich. ^^
Ich hab für meine Appbar einen ClipboardViewer geschrieben er ermöglicht das Zwischenspeichern und wiederaufrufen von Clipboardeinträgen (Bilder, Text, Dateien, etc..). Nun hab ich zwei Probleme:
1. Wenn ich per SetData() daten ins Clipboard schreibe wird WM_DRAWCLIPBOARD 2mal vom System ausgegeben. Auch wenn ich z.B. im Firefox Text kopiere, jedoch nicht wenn ich in Notepad Text kopiere. Einige Seiten im Internet behaupten das durch eine falsche Verwendung der Clipboard API dieser Fehler auftritt. Nun mach ich aber doch eigentlich nichts falsch in der SetData() Methode, oder? Und NEIN innerhalb des Programms wir die Methode NICHT 2mal aufgerufen!
2. Ab und an nach gewisser Laufzeit schmiert OnClipboardChange() mit einem Stackoverflow Error ab. Das kann ich mir absolut nicht erklären. Je nachdem welchen Inhalt man gerade kopiert hat (von einem anderen Programm aus) z.B. Text tritt der Stackoverflow innerhalb der Funktion (in dem Fall) Clipboard.ContainsText() auf.
Weis hier jemand evtl. rat?
Hier die Klasse:
/// <summary>
/// Clipboardformate.
/// </summary>
public enum CBDataType
{
/// <summary>
/// Nicht untersüztes Clipboardformat
/// </summary>
Unsupported,
/// <summary>
/// Daten im Filelist-Format vorhanden.
/// </summary>
Files,
/// <summary>
/// Format im Audio-Format vorhanden.
/// </summary>
Audio,
/// <summary>
/// Format im Image-Format vorhanden.
/// </summary>
Image,
/// <summary>
/// Format im Text-Format vorhanden.
/// </summary>
Text,
}
public delegate void ClipboardWatcherOnChangeEventHandler(CBDataType type, object data);
public class ClipboardWatcher
{
#region WIN API
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
[DllImport("user32.dll")]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr GetClipboardOwner();
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll")]
static extern uint GetCurrentProcessId();
private const UInt32 WM_CHANGECBCHAIN = 0x030D;
private const UInt32 WM_DRAWCLIPBOARD = 0x0308;
private const UInt32 WM_CLOSE = 0x0010;
private const UInt32 WM_DESTROY = 0x0002;
#endregion
private static bool _instance = false;
private IntPtr _nextCBWatcher;
private IntPtr _ownerWnd;
private bool _wasReset;
public event ClipboardWatcherOnChangeEventHandler ClipboardChange;
public ClipboardWatcher(IntPtr OwnerWnd)
{
ClipboardChange = null;
_nextCBWatcher = IntPtr.Zero;
_ownerWnd = OwnerWnd;
_nextCBWatcher = SetClipboardViewer(_ownerWnd);
if (_instance) throw new Exception("Only one instance at a time. TODO: Check SetData() triggering twice our MessageProc...");
_instance = true;
_wasReset = false;
}
public static void SetData(CBDataType type, object data)
{
object dat;
switch (type)
{
case CBDataType.Files:
dat = data as StringCollection;
if (dat == null) throw new Exception("Invalid data.");
Clipboard.SetFileDropList((StringCollection)dat);
break;
case CBDataType.Audio:
dat = data as Stream;
if (dat == null) throw new Exception("Invalid data.");
Clipboard.SetAudio((Stream)dat);
break;
case CBDataType.Image:
dat = data as Image;
if (dat == null) throw new Exception("Invalid data.");
Clipboard.SetImage((Image)dat);
break;
case CBDataType.Text:
dat = data as string;
if (dat == null) throw new Exception("Invalid data.");
Clipboard.SetText((string)dat);
break;
default: throw new Exception("Unsupported Clipboardformat.");
}
}
public void SetClipboardViewer()
{
_wasReset = true;
ChangeClipboardChain(_ownerWnd, _nextCBWatcher);
_nextCBWatcher = SetClipboardViewer(_ownerWnd);
}
public void MessageProc(ref Message m)
{
if (m.Msg == WM_CHANGECBCHAIN)
{
if (m.WParam == _nextCBWatcher)
{
_nextCBWatcher = m.LParam;
}
else
{
SendMessage(_nextCBWatcher, m.Msg, m.WParam, m.LParam);
}
}
else if (m.Msg == WM_DRAWCLIPBOARD)
{
uint cpid = 0, pid = 0;
if (_wasReset)
{
_wasReset = false;
return;
}
GetWindowThreadProcessId(GetClipboardOwner(), out pid);
cpid = GetCurrentProcessId();
if (pid != cpid)
OnClipboardChange();
if (_nextCBWatcher != IntPtr.Zero)
SendMessage(_nextCBWatcher, m.Msg, m.WParam, m.LParam);
}
else if (m.Msg == WM_DESTROY)
{
ChangeClipboardChain(_ownerWnd, _nextCBWatcher);
}
}
protected virtual void OnClipboardChange()
{
object obj = null;
CBDataType objType = CBDataType.Unsupported;
if (Clipboard.ContainsFileDropList())
{
obj = Clipboard.GetFileDropList();
objType = CBDataType.Files;
}
else if (Clipboard.ContainsAudio())
{
obj = Clipboard.GetAudioStream();
objType = CBDataType.Audio;
}
else if (Clipboard.ContainsImage())
{
obj = Clipboard.GetImage();
objType = CBDataType.Image;
}
else if (Clipboard.ContainsText())
{
obj = Clipboard.GetText();
objType = CBDataType.Text;
}
else
obj = Clipboard.GetDataObject();
Control ctrl = ClipboardChange.Target as Control;
if (ClipboardChange != null)
{
if (ctrl != null && ctrl.InvokeRequired)
ClipboardChange.Invoke(objType, obj);
else
ClipboardChange(objType, obj);
}
}
}
Der Thread hat mich auch nicht weiter gebracht. Hab nun für die Items einen cache angelegt das verbessert das flackern ein wenig aber entfernt es auch nicht komplett.
ich hatte mich einige zeit zur Ruhe gesetzt und bin wieder ein bisschen am Programmieren ;) zu meinem Problem:
jedesmal wenn ich in meiner ListBox ein Item abwähle, sprich wenn ich ein anderes Item neu Selektiere, flackert das abgewählte item. Ich hab echt alles versucht überall rum gegooglet aber ich habe keine Ahnung was da passiert und warum es flackert. :(
Wen es interessiert hier mal ein Bld vom Projekt (und der ListBox): siehe Anhang
Hier mal der code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DrawingEx;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace substx
{
class DesignListBox : ListBox
{
public DesignListBox()
{
base.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint,
true);
// DoubleBuffered = true; <-- nutzt auch nix WAH!!!
base.DrawMode = DrawMode.OwnerDrawFixed;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
Rectangle bnd = e.Bounds;
Graphics dc = e.Graphics;
ColorTable ct = (ColorTable)Items[e.Index];
int pad = 6;
int pwh = bnd.Height - 2 * pad;
Rectangle pi0 = new Rectangle(bnd.X + pad, bnd.Y + pad, pwh, pwh);
Rectangle pi1 = new Rectangle(bnd.X + pi0.Right + pad, bnd.Y + pad, pwh, pwh);
Rectangle pi2 = new Rectangle(bnd.X + pi1.Right + pad, bnd.Y + pad, pwh, pwh);
Rectangle pi3 = new Rectangle(bnd.X + pi2.Right + pad, bnd.Y + pad, pwh, pwh);
if (ct == null)
{
#region Error
dc.FillRectangle(new SolidBrush(BackColor), bnd);
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
dc.DrawString("Error Item.", Font, new SolidBrush(Color.Red), bnd, sf);
#endregion
}
else
{
#region Preview
dc.SetColorTableWindowsVista(ct);
dc.FillRectangle(new SolidBrush(ct.Background), bnd);
dc.DrawVistaButtonBackground(pi0, 2, true, false, false);
dc.DrawVistaButtonBackground(pi1, 2, true, true, false);
dc.DrawVistaButtonBackground(pi2, 2, true, false, true);
dc.DrawVistaButtonBackground(pi3, 2, true, true, true);
Rectangle capt = bnd; capt.X += 8; capt.Width -= 8;
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
dc.DrawString(ct.Name + ((ct == Design.ColorTable) ? " (Aktiv)" : ""), Font, new SolidBrush(ct.Text), capt, sf);
#endregion
}
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
#region Selection
Rectangle sel = bnd;
Rectangle selhalf;
Color selcl = Color.CornflowerBlue;
sel.Inflate(-2, -2);
using (GraphicsPath psel = RoundedRectangle.Create(sel, 2))
{
using (Pen selouter = new Pen(Color.FromArgb(75, selcl)))
{
dc.DrawPath(selouter, psel);
}
}
sel.Inflate(-1, -1);
selhalf = sel;
selhalf.Height /= 2;
using (GraphicsPath psel = RoundedRectangle.Create(selhalf, 2,
RoundedRectangle.RectangleCorners.TopLeft &
RoundedRectangle.RectangleCorners.TopRight))
{
selhalf.Height++;
using (LinearGradientBrush lgb = new LinearGradientBrush(
selhalf, Color.FromArgb(150, selcl), Color.Transparent, 90f))
{
dc.FillPath(lgb, psel);
}
}
using (GraphicsPath psel = RoundedRectangle.Create(sel, 2))
using (Pen selinner = new Pen(Color.FromArgb(150, selcl)))
{
dc.DrawPath(selinner, psel);
}
#endregion
}
}
}
}
falls dich das interessieren sollte: http://www.un4seen.com/ super audio libs haben die da u.a. auch streaming usw. möglich.. recht einfach und übersichtlich das ganze. allerdings glaub ich audio only
Diese Nodes sind alle OwnerDrawn (geht aus dem code hervor) und sollen sich auch möglichst in "echtzeit" an den inhalt des programms anpassen... um also eine Statusänderung einer Node anzuzeigen sollte auch nur eine Node neu gezeichnet werden und nicht der ganze sichtbare bereich..
Hallo ich hab hier mal eine Lösung wie man eine einzige TreeNode in einem TreeView aktualisieren kann. Ich frag mich jetzt obs da einen besseren weg gibt.
was ich an dem punkt nicht verstehe ist das die anzeige nach ausführen von UpdateSingleNode auch tatsächlich sofort aktualisiert ist! Irgentwie hab ich immer gedacht man müsste dem control bzw win explizit mitteilen das sich was geändert hat?!
const int TV_FIRST = 0x1100;
const int TVM_GETITEMRECT = (TV_FIRST + 4);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private void UpdateSingleNode(TreeNode node)
{
if (node.IsVisible)
{
RECT rc;
unsafe
{
*(void**)&rc = node.Handle.ToPointer();
SendMessage(Handle, TVM_GETITEMRECT, IntPtr.Zero, new IntPtr(&rc));
}
// dc der treeview holen
using (Graphics dc = Graphics.FromHwnd(Handle))
{
// erstelle set mit atm verarbeiteten states
TreeNodeStates states = TreeNodeStates.Default;
states |= node.IsSelected ? TreeNodeStates.Selected : TreeNodeStates.Default;
// sende ondrawnode
OnDrawNode(new DrawTreeNodeEventArgs(dc, node, rc.ToRectangle(), states));
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
int _left;
int _top;
int _right;
int _bottom;
public RECT(global::System.Drawing.Rectangle rectangle)
: this(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom)
{
}
public RECT(int left, int top, int right, int bottom)
{
_left = left;
_top = top;
_right = right;
_bottom = bottom;
}
public int X
{
get { return Left; }
set { Left = value; }
}
public int Y
{
get { return Top; }
set { Top = value; }
}
public int Left
{
get { return _left; }
set { _left = value; }
}
public int Top
{
get { return _top; }
set { _top = value; }
}
public int Right
{
get { return _right; }
set { _right = value; }
}
public int Bottom
{
get { return _bottom; }
set { _bottom = value; }
}
public int Height
{
get { return Bottom - Top; }
set { Bottom = value - Top; }
}
public int Width
{
get { return Right - Left; }
set { Right = value + Left; }
}
public global::System.Drawing.Point Location
{
get { return new global::System.Drawing.Point(Left, Top); }
set
{
Left = value.X;
Top = value.Y;
}
}
public global::System.Drawing.Size Size
{
get { return new global::System.Drawing.Size(Width, Height); }
set
{
Right = value.Width + Left;
Bottom = value.Height + Top;
}
}
public global::System.Drawing.Rectangle ToRectangle()
{
return new global::System.Drawing.Rectangle(this.Left, this.Top, this.Width, this.Height);
}
public static global::System.Drawing.Rectangle ToRectangle(RECT Rectangle)
{
return Rectangle.ToRectangle();
}
public static RECT FromRectangle(global::System.Drawing.Rectangle Rectangle)
{
return new RECT(Rectangle.Left, Rectangle.Top, Rectangle.Right, Rectangle.Bottom);
}
}
Okay war bissl blöd hab doch ne doku gefunden und schnell selbst was gebastelt für meine zwecke reichts:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
namespace GamesVerwaltung
{
class MultiIcon
{
private struct TIconHeader
{
public short res0;
public short imgtype;
public short imgcount;
}
private struct TIconData
{
public byte width;
public byte height;
public byte clcount;
public byte res0;
public short clplanes;
public short bpp;
public int imglen;
public int imgadr;
}
private Bitmap[] bitmaps;
private TIconData[] icondata;
private TIconHeader iconheader;
public MultiIcon()
{
bitmaps = new Bitmap[6];
icondata = new TIconData[6];
iconheader = new TIconHeader();
iconheader.imgcount = 6;
iconheader.imgtype = 1;
iconheader.res0 = 0;
}
private void setImage(int idx, Bitmap bmp)
{
bitmaps[idx] = bmp;
icondata[idx].bpp = 32;
icondata[idx].clcount = 0;
icondata[idx].clplanes = 0;
icondata[idx].height = (byte)(bmp.Height == 256 ? 0 : bmp.Height);
icondata[idx].width = (byte)(bmp.Width == 256 ? 0 : bmp.Width);
icondata[idx].res0 = 0;
icondata[idx].imgadr = -1;
icondata[idx].imglen = -1;
}
public void SetAll(Image img)
{
setImage(0, createHighRes(img, 16, 16));
setImage(1, createHighRes(img, 24, 24));
setImage(2, createHighRes(img, 32, 32));
setImage(3, createHighRes(img, 48, 48));
setImage(4, createHighRes(img, 128, 128));
setImage(5, createHighRes(img, 256, 256));
}
public void Save(string file)
{
FileStream fstr = new FileStream(file, FileMode.Create, FileAccess.Write);
writeIcon(fstr);
fstr.Close();
fstr.Dispose();
}
private void writeIcon(Stream str)
{
BinaryWriter bw = new BinaryWriter(str);
bw.Write(iconheader.res0);
bw.Write(iconheader.imgtype);
bw.Write(iconheader.imgcount);
int offset = 6 /*ANZAHL DER BILDER*/ * 16 /*BYTEGRÖßE ICONHEADER*/;
int iconheader0offset = (int)str.Position;
str.Position += offset;
for (int i = 0; i < 6; i++)
{
Bitmap bmp = bitmaps[i];
//MemoryStream mstr = new MemoryStream();
icondata[i].imgadr = (int)str.Position;
bmp.Save(str, System.Drawing.Imaging.ImageFormat.Png);
icondata[i].imglen = (int)(str.Position - icondata[i].imgadr);
}
str.Position = iconheader0offset;
for (int i = 0; i < 6; i++)
{
TIconData idat = icondata[i];
/*
0 1 Specifies image width in pixels. Can be 0, 255 or a number between 0 to 255. Should be 0 if image width is 256 pixels.
1 1 Specifies image height in pixels. Can be 0, 255 or a number between 0 to 255. Should be 0 if image height is 256 pixels.
2 1 Specifies number of colors in the color palette. Should be 0 if the image is truecolor.
3 1 Reserved. Should be 0.[Notes 1]
4 2 In .ICO format: Specifies color planes. Should be 0 or 1.[Notes 2]
6 2 In .ICO format: Specifies bits per pixel. [Notes 3]
8 4 Specifies the size of the bitmap data in bytes
12 4 Specifies the offset of bitmap data address in the file
*/
bw.Write(idat.width);
bw.Write(idat.height);
bw.Write(idat.clcount);
bw.Write(idat.res0);
bw.Write(idat.clplanes);
bw.Write(idat.bpp);
bw.Write(idat.imglen);
bw.Write(idat.imgadr);
}
}
private Bitmap createHighRes(Image img, int w, int h)
{
Bitmap bmp = new Bitmap(w, h);
Graphics dc = Graphics.FromImage(bmp);
dc.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
dc.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
dc.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
dc.DrawImage(img, 0, 0, w, h);
dc.Dispose();
return bmp;
}
}
}
Ab Win Vista (oder schon eher??) unterstützt der Windows-Explorer ja dieses neue Iconformat (256x256 PNG Compressed Icons). Nun wollte ich wissen ob jemand guten Code kennt der solche Icons erstellt? Eine Doku für das Dateiformat damit ich selbst "handanlegen" kann wär auch okay. Irgendwie find ich nix. :)
Ja klasse!! Bin ich auch gerade drüber gestolpert hab mir das Kostenlose EBook "Android Grundlagen und Programmierung" über heise developer geladen... da les ich da auf dem index myCSharp... da hab ich mir gedacht das kennste doch? ^^
Erstmal recht herzlichen Glückwunsch dazu!!
EDIT:
Zitat von winSharp93
[offtopic]
Zitat von heise Developer
Know-how 11.03.2010 - 13:36
Schade, leider 1 Minute zu früh veröffentlicht :D[/offtopic]
hab ich überhaupt schonmal erwähnt wie überaus hilfreich und informativ dieses Forum ist? Die moderation hier ist super, die Leute immer sachlich und es wird geholfen. Eigentlich alles was man von so einem Forum erwartet wird hier bestens erfüllt. Darum sag ich einfach mal: Danke.
ja war auch ein bisschen unglücklich die wortwahl. Den ersten schritt den ich jetzt gemacht habe ist die fps-rate zu errechnen. Nun muss ich nur noch beim unterschreiten der fps die geschwindigkeit des scrollens anpassen da hakts aber noch ein bisschen. Release den pbv aber erstmal ohne dieses feature da das doch mehr gehirnschmalz erfordert. hab ich das feature erstmal in ein eigenes projekt gekapselt.
Hm. Das man schnellst möglich ankommen möchte ist ein gutes argument. Picasa kann das aber auch ziemlich flott hängt aber auch bestimmt nicht an der GDI+ :/. Ist vllt auch etwas hoch gegriffen. Nur hätt ja sein könn das sich da jemand schonmal gedanken drüber gemacht hat wär ziemlich informativ. Werd dann wohl mal bissl Pionierarbeit leisten. Lass euch das aber wissen wenn ich was brauchbares erreiche ^^
hat da jemand nen kleinen denkanstoß für mich? lieg gerad irgentwie auf dem trockenen :/
man kann ja noch so performanten code haben wie man will iwann fängts immer an zu ruckeln ich bin z.Z. an einem Photoshop Brush Viewer (80% rdy :)) und wenn ich unter voller auflösung ca. 10x9 brushes darstelle (ist auch alles gecached und so keine frage) fängts halt an zu ruckeln beim scrollen. Nun möcht ich wissen ob sich darüber schonmal jemand gedanken gemacht hat wie man ermitteln kann wann man die echtzeit verlässt um so z.B. zu schnelles scrollen zu unterdrücken.
sagt man das so? echtzeit verlassen? hört sich jetzt iwie nach marty und dem doc an ;)
[EDIT] aha. nu klappts. ich hab die var-typen von uint nach long umgestellt. GetWindowLong() liefert bei mir einen negativen wert den ich nun negiert habe. keine ahnung warum da ein negativer wert rumkommt...
Öhm ja, die SysListView32 hat halt den Style WS_CHILDWINDOW. Alle Fenster mit diesem stil brauchen logischerweise erst garnicht geprüft werden weil die sich nicht unter die Appbar schieben können.
Doch da gibts jetzt auch schon direkt ein neues Problem:
1. Die Seiten müssten erstmal als Form erstellt werden. Programm intern musst du diese Form's dann erzeugen und den Parent auf das Handle des TabPanel setzen. Wenn das klappt sollte die Seite innerhalb des Tabs als Fenster erscheinen. Dann kannst du noch die Border der Form anpassen so das sie nicht mehr als Form zu erkennen ist.
2. Nun musst du nur noch den Drag&Drop mechanismus entwerfen der das in 1. beschriebene vorgehen automatisiert. (in beide Richtungen)