Laden...
U
Benutzerbeschreibung
Konto auf Wunsch des Benutzers gesperrt

Forenbeiträge von userid14268 Ingesamt 1.578 Beiträge

26.04.2011 - 07:53 Uhr

Die Fehlermeldung sagt es doch ganz deutlich. Er such das Property im "Control" objekt, aber das bringt dir ja nichts.
Dein "ControlTemplate" gibt kein TargetType an, also sucht er im fallback, das ist dann das Control.

> Das Style kennt dein FilterView Control nicht.

Wenn du ein Custom Control schreiben willst, dann mach das auch richtig.

  1. Erstelle eine Neue Klasse FilterView : ListBox (hast du schon)
  2. Gib der Klasse einen static ctor
static FilterView()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(FilterView), new FrameworkPropertyMetadata(typeof(FilterView)));
}
  1. Erstelle ein Ordner "Themes" im Projekt
  2. In diesem Ordner erstelle ein "Generic.xaml" Resource dictionary
  3. In diesem Ordner machst du dein namespace bekannt
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                               xmlns:Controls="clr-namespace:UI.Controls">
  1. Und nun verleihst du dein Control sein aussehen
<Style TargetType="{x:Type Controls:FilterView}">
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Rounding" Value="2"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Controls:FilterView}">
                <Border BorderBrush="{TemplateBinding BorderBrush}"
                             BorderThickness="{TemplateBinding BorderThickness}"
                             Background="{TemplateBinding Background}"
                             CornerRadius="{TemplateBinding Rounding}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Nun kannst du das Control ganz normal verwenden wie du es von den normalen Controls kennst. Auch das Style brauchst du nicht angeben.

<Controls:FilterView Rounding="10">
<!-- ... -->
25.04.2011 - 20:43 Uhr

Allgemein scheint das Problem ja sowieso eher begrenzter Natur zu sein, da es nicht an jeder Ecke im Web Meldungen dazu gibt. Daher würd ich auf gar keinen Fall generell von x64 bzw. AnyCPU als Targetplattform abraten (auch wenns dich konkret ja schon trifft) Ich vermute das liegt eher daran das die meisten es auf x86 lassen 😄 Und die die es umstellen wollten und auf die Probleme stießen habens dann einfach zurückgestellt, kurz auf MS gemeckert, und weiter gemacht.

Ich merk sehr oft das es sehr viele Menschen gibt die komplett ohne Foren oder ähnliches leben und vor allem Arbeiten.

25.04.2011 - 19:55 Uhr

Die üblichen Verdächtigen sind erstmal die ganzen verschiedenen Virenscanner und sonstige Securitysoftware welche sich beim Start eines Programms einmischen. Welche verwendest du dort? Keine 😉
(Selbst wenn ich solche Software verwenden würde, dann währe doch nicht nur die x64 betroffen?)

Im übrigen, Ich kann das Problem auf Arbeit auch nachstellen.
Hier daheim wie gesagt ist es ein i5 mit 6GB Ram und eine 1 GB ATI Graka, auf Arbeit ist es n Pentium D mit 2 GB RAM und einer noname Graka (aber auch Tier 3)

Unabhängig davon seh ich das doch richtig, alle Kunden müssten das (ngen update) auch auf ihren PC ausführen, Richtig?

25.04.2011 - 18:35 Uhr

Den Link kenn ich, hab ich auch schon ausprobiert. (Das NGEN update auf die 64 Bit assemblies) (Wird auch hier geschrieben: .NET 4.0 WPF x64 Slow Application Startup)
=> Brachte keinerlei erfolg!

Start eines Fensters erst nach 10 Sekunden, und auch Popups tauchen (beim ersten mal) erst 2 Sekunden später auf.

Die Performance von den WPF oberflächen ist im vergleich zu den x86 abartig schlecht.
(Auf ein i5 mit einem 1GB Ati Radeon)

Neues Projekt erstellt:

<Window x:Class="Demo.MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		Title="MainWindow"
		Height="350"
		Width="525">
	<DockPanel>
		<Menu DockPanel.Dock="Top">
			<MenuItem Header="File">
				<MenuItem Header="First" />
				<MenuItem Header="Second" />
				<MenuItem Header="Third" />
			</MenuItem>
		</Menu>
		
		<StatusBar DockPanel.Dock="Bottom">
			<TextBlock Text="Ready" />
		</StatusBar>
		
		<Grid />
	</DockPanel>
</Window>

Mehr nicht.
Also x86 gebaut und ausgeführt, das Fenster ist sofort da nach ausfürhung der exe. Das Menu geht auch sofort auf.
Als x64 gebaut, das Fenster braucht ~5 Sekunden bis es mit inhalt da ist (der Rahmen war ein stück schneller als der Client bereich)
Das Menü braucht ~2 Sekunden bis es auf geht.

  • CMD (als Admin) gestartet und zum "C:\Windows\Microsoft.NET\Framework64\v4.0.30319" pfad gewechselt
  • NGen update aufgerufen (dauerte dann eine weile)
  • Windows neu gestartet (weiß nicht ob das notwendig war)
  • Die applikation komplett neu gebaut (sicherheitshalber die bin und obj Ordner gelöscht)
    => Kein unterschied zu vorher.

Unabhängig davon ob es bei manchen funktioniert (aber warum bei mir nicht?) Das würde am Ende doch bedeuten das alle Kunden die die WPF Applikation verwenden wollen das NGEN update aufrufen müssen? Finde das alles ziemlich Banane...

Solange alle Kunden ihren PC derart "patchen" müssten ist ein x86 build die einzigste alternative!

25.04.2011 - 10:33 Uhr

PS.

WPF Anwendung immer als x86 bauen, AnyCpu wird auf den 64Bit system als x64 interpretiert., und das hat bei WPF massive performance einbußen zur folge:

WPF Fensters startet bei x64 oder anycpu deutlich langsamer als bei x86

Die Bestätigung habe ich später nach noch mehr Recherche auch woanders noch gefunden.

Darum ist die Standardkonfiguration eines WPF Projektes auch auf einer 64Bit Maschine x86.

21.04.2011 - 15:39 Uhr

Die TabItems sind auch nur HeaderedContentControls und das TabControl ein ItemsControl.

  1. Du kannst pro Tab ein UserControl haben und im Code die ViewModels für jede Seite in einer Liste halten. Diese liste auf das TabControl.ItemsSource binden und durch die Resourcen das richtige UserControl automatisch setzen lassen. (MVVM Weg)
    => Liste neu Sortieren.

  2. Du kannst einfach die UserControls im Code halten und gegen TabControl.ItemsSource binden.
    => Liste neu Sortieren.

  3. Du kannst die TabControl.Items liste modifizieren.
    => Weiß nicht wie man das am Besten macht.

21.04.2011 - 14:16 Uhr

Das ist auch wieder ein dämlich Blend SDK behavior - es wir noch nichtmal erklärt wie man das SelectedItem wieder setzt, man muss es im Baum dann auch noch Suchen...

//Dazu
Gerade mal in UltraEdit getickert:

public class ItemSelectedBehavior : DependencyObject
{
    public static object GetSelectedItem(DependencyObject obj)
    {
        return (object)obj.GetValue(SelectedItemProperty);
    }

    public static void SetSelectedItem(DependencyObject obj, ICommand value)
    {
        obj.SetValue(SelectedItemProperty, value);
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(ItemSelectedBehavior), new UIPropertyMetadata(OnSelectedItemChanged));

    private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var tree = sender as TreeView;
        if (tree.Tag == null)
        {
            tree.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(Element_SelectedItemChanged);
            return;
        }
        var isSelfCheck = (bool)tree.Tag;
        if (!isSelfCheck)
        {
            tree.Tag = true;
            // find item in the tree somehow and select it
            tree.Tag = false;
        }
    }

    private static void Element_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        var tree = (TreeView)sender;
        tree.Tag = true;
        SetSelectedItem(tree, e.NewValue);
        tree.Tag = false;
    }
}

So ähnlich müsste es dann gehen, man muss dann nur schauen das man mit dem "SelfCheck" nicht durcheinander kommt um in keine Endlosschleife zu geraten.
Dann müsste man mit solch ein Behavior TwoWay binden können.

20.04.2011 - 17:10 Uhr

Dann packs in einem Globalen "Styles" ResourceDictionary.
Einfacher als XAML geht nicht, Template im C# Code ist um Welten schlechter zu Maintainen.

20.04.2011 - 13:04 Uhr

GridSplitter bekommen bei mir immer eine eigene Spalte oder Reihe und geben auch dessen Größe vor.
Das macht das ganze sehr übersichtlich 😃

In deinem Beispiel hast du beide Controls in der selben Column, wenn das beabsichtigt ist dann musst du den text ein Margin so breit geben wie der Splitter.

<TextBox Text="blabla" TextWrapping="Wrap" TextAlignment="Right" Margin="8,0,0,0" />
<GridSplitter Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="8" HorizontalAlignment="Left" />

Das ist aber alles Doof.

Damals hat MS uns selbst gesagt (Ende 2008 als wir ne Schulung von nem MS Menschen bekamen) das sie es so empfehlen:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" /> <!-- With will be set by the splitter itself -->
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <!-- First Column -->
    <TextBox Text="blabla" TextWrapping="Wrap" TextAlignment="Right" />

    <!-- Splitter in Second column -->
    <GridSplitter Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="8" />

    <!-- Anything else in Third column -->
    <Control Grid.Column="2" />

</Grid>

Ich mach das immer so und es ist sehr angenehm, man braucht da nicht mit Werten rum mauscheln.

20.04.2011 - 12:15 Uhr

Warum zum Geier machst du die Templates im Code? Sowas les ich prinzipiell nicht durch 😁

20.04.2011 - 12:12 Uhr

Ein WrapPanel kann nicht Scrollen.

Was du machen kannst ist das WrapPanel in einem ScrollViewer zu hosten, bei diesem musst du nur darauf achten die entsprechende ScrollBar die nicht erscheinen darf zu deaktivieren.

z.b.

<ScrollViewer HorizontalScrollBarVisibility="Disabled">
    <WrapPanel />
</ScrollViewer>
20.04.2011 - 11:36 Uhr

Du bindest den Command entsprechend mit RelativeSource.

<Button Command="{Binding DataContext.AnythingCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />

Also man sucht sich mit RelativeSource das Fenster, und aus dessen DataContext schnappt man sich den Command 😃

20.04.2011 - 11:30 Uhr

Wie sehn deine Templates aus?

20.04.2011 - 11:28 Uhr

Bei welchem Add?

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height=".4*" />
        <RowDefinition Height="Auto" />
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
<Grid>

Nun sag mir wo ich die GridSplitter haben möchte 😉 Und auch wie die ColumSpan und/oder RowSpan aussehen sollen.

20.04.2011 - 10:29 Uhr

Automatisch erstellen stell ich mir Kompliziert vor, auch wenn man es optional anbietet ("EnableAutoSplitter") was soll er machen wenn man zb 4 Columns und 4 Rows hat - In welchen Columns/Rows? Wie ist das mit dem Column-, RowSpan? usw usf

Lieber manuell, das ist doch kein Akt.

..
<ColumnDefinition Width="Auto" />
..
<GridSplitter Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="4" />

19.04.2011 - 17:34 Uhr

bin zwar in WPF noch nicht so lange unterwegs aber wenn du nur das aktuell ausgewählte Item wissen willst, dann solltest du die Liste die an dein TreeView geht als "ListCollectionView" definieren, da kannst du dann einfach das aktuell ausgewählte item mit "CurrentItem" herausfinden.

Das müsste er mit jedem Level machen, und kann auch nur auf den jeweiligen Level darauf reagieren, ein SelectedItem für alle Tiefen im MainViewModel geht so nicht

Wenn du auf das Event selbst reagieren willst dann würde ich dir folgendes vorschlagen mal durchzulesen:


>
Das sind die Behaviors aus den Blend SDK.
Das hat aber nachteile: Man braucht das Blend SDK und muss die dll Dateien mit Deployen da es nicht fest im .Net enthalten ist.
Dann doch lieber ein direkten Behavior wie ich das bereits zeigte. Keine zusätzlichen dlls, kein SDK muss extra installiert werden.

19.04.2011 - 13:39 Uhr

Hast du OpenedTemplate und ClosedTemplate auch gesetzt?

Ich mach das immer so:

<Window.Resources>
    <Controls:DetailsTemplateSelector x:Key="DetailsTemplateSelector" />
</Window.Resources>

<ComboBox ItemsSource="{Binding Items}"
                   ItemTemplateSelector="{StaticResource DetailsTemplateSelector}">
    <ComboBox.Resources>
        <DataTemplate x:Key="Opened">
            <StackPanel>
                <TextBlock Text="{Binding First}" />
                <TextBlock Text="{Binding Second}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="Closed">
            <TextBlock Text="{Binding First}" />
        </DataTemplate>
    </ComboBox.Resources>
</ComboBox>
public class DetailsTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var parent = ((FrameworkElement)container).TemplatedParent;
        if (parent is ComboBox)
            return ((ComboBox)parent).FindResource("Closed") as DataTemplate;
        else if (parent is ComboBoxItem)
            return ((ComboBoxItem)parent).FindResource("Opened") as DataTemplate;
        return null;
    }
}

Das tut auch, grad ma probiert.

19.04.2011 - 09:06 Uhr

Wenn du Anfänger bist musst du lernen, also geb ich dir nur Stichworte:

Was du brauchst ist die "DelegateCommand" Klasse, manchmal auch "RelayCommand" genannt, die findest du zuhauf wenn du Googles (Auch hier im Forum bestimmt).
Mit dieser verbindest du ein ICommand zu einer Methode. (Über Lambda)

Desweiteren ist dieses "Behavior" ein "Attached Behavior".

Such danach und lern es durch anwendung 😃

18.04.2011 - 16:06 Uhr

Ein DataTemplateSelector ist die einzigste saubere Lösung, alles andere ist Gefummel und Trixerei. Genau dafür ist diese funktionalität vorhancen.

if item.IsSelected then
    return ShortTemplate
else
    return NormalTemplate
end if
18.04.2011 - 15:57 Uhr

Bis auf das initialisieren des ItemSelectedCommand im ctor des ViewModels ist alles ersichtlich.

Ist ItemSelectedCommand bei dir auf eine Instanz gesetzt? Das hab ich nämlich weg gelassen um zu sehen ob du es versuchst du verstehen oder nur direkt übernimmst :evil:

ItemSelectedCommand musst doch irgendwie auf die ItemSelected Methode zeigen 😉, der ist wenn du es nicht machst die ganze Zeit null und dann geht natürlich nichts.

public ctor()
{
	ItemSelectedCommand = new DelegateCommand(p => ItemSelected(p));
}

Das nächste mal versuch es zu verstehen statt einfach nur Copy&Paste.

18.04.2011 - 09:36 Uhr

Ich habe die Vermutung der der Standardhintergrund einer Zelle x:Null ist, also bekommt es den mouse over nicht mit.

18.04.2011 - 09:35 Uhr

Bis auf das initialisieren des ItemSelectedCommand im ctor des ViewModels ist alles ersichtlich.

>> Wo muss das Behavior hin?
Siehe zweiter Code Block.

>> Und wie reagiere ich beispielsweise auf das SelectionChanged Event der Treeview?
Das behavior reagiert bereits drauf und schickt ein Command, siehe ersten Code Block.

17.04.2011 - 21:19 Uhr

In einer TreeView kann man das SelectedItem leider nicht binden.
Abhilfe gibt da aber ein einfaches Behavior:

Behavior

public class ItemSelectedBehavior : DependencyObject
{
	public static ICommand GetSelectedCommand(DependencyObject obj)
	{
		return (ICommand)obj.GetValue(SelectedCommandProperty);
	}

	public static void SetSelectedCommand(DependencyObject obj, ICommand value)
	{
		obj.SetValue(SelectedCommandProperty, value);
	}

	public static readonly DependencyProperty SelectedCommandProperty =
		DependencyProperty.RegisterAttached("SelectedCommand", typeof(ICommand), typeof(ItemSelectedBehavior), new UIPropertyMetadata(OnSelectedCommandChanged));

	private static void OnSelectedCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
	{
		var element = sender as TreeView;
		if (element != null)
			element.SelectedItemChanged +=new RoutedPropertyChangedEventHandler<object>(Element_SelectedItemChanged);
	}

	private static void Element_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
	{
		var command = GetSelectedCommand((DependencyObject)sender);
		if (command != null &&
			command.CanExecute(e.NewValue))
			command.Execute(e.NewValue);
	}
}

View

<TreeView ItemsSource="{Binding Items}" Views:ItemSelectedBehavior.SelectedCommand="{Binding ItemSelectedCommand}" />

ViewModel

public object SelectedItem
{
	get { return _selectedItem; }
	set
	{
		_selectedItem = value;
		NotifyPropertyChanged(() => SelectedItem);
	}
}
private object _selectedItem;

public ICommand ItemSelectedCommand { get; set; }
private void ItemSelected(object e)
{
	SelectedItem = e;
}

Dann geht es wenigstens OneWay

16.04.2011 - 11:23 Uhr

Setz mal noch
<Setter Property="Background" Value="Transparent" />
im CellStyle. Ändert das etwas?

11.04.2011 - 11:36 Uhr

Was du suchst nennt sich "TreeListView"

08.04.2011 - 14:04 Uhr

Beachte: Wenn du ein Window Icon verwendest welches intern auch das 256x256 Format beinhaltet, dann knallts unter XP.

[gelöst] *.ico als Icon mehrfach verwenden unter XP => Crash

08.04.2011 - 08:53 Uhr

Die Fehlermeldung passt nicht zu deinem gezeigten Code.

Oben im Code bindest du gegen "SelectedIndex" aber die Fehlermeldung sucht nach "SelectedItem"

CommandParameter="{Binding ElementName=cbxPortName,Path=SelectedIndex,Mode=OneWay}"
vs
BindingExpression:Path=SelectedItem;

07.04.2011 - 20:43 Uhr

Wie lautet die Fehlermeldung genau? Error Code 4 "Ein Binding Fehler" reicht nicht als info.

06.04.2011 - 20:47 Uhr

Ich habe mir damit auch schon beschäftigt und auch mit dem Reflektor fand ich nicht raus wie die ComboBox dieses Voodoo macht.

Ich habe es in meiner TreeComboBox so gelöst das ich beim Laden des Controls mir das Fenster suche (Am ende gibt es ja immer eins) und dort das PreviewMouseDown sowie SizeChanged aboniere. Sobald das kommt und meine ComboBox war nicht angeklickt und ist offen, dann wird es geschlossen.
Fummelig aber die einzigste möglichkeit die ich fand.

Hier ist der Code wo du es sehen kannst.

Was ich nicht hinbekommen habe ist das es auch schließt wenn das Fenster verschoben wurde. Ich war schon im WinApi hook beim GetMinMax, nur dann müsste ich von dort aus irgendwie in den Client bereich zu mein Control kommen. Das habe ich noch auf meiner ToDo, das ist noch fummeliger.

//Dazu
Ich hatte noch eine idee zu meinem entry auf die ToDo geschrieben.
Und zwar hatte ich die Idee mich in den WinApi handler ein zu klinken und beim GetMinMax das Resize und Move zu fangen und über ein kleinen "Mediator" zu dem Control schicken der das popup dann bei bedarf zu macht.

Das Problem ist ja das die Maus klicks außerhalb des Client bereichs nur per WinApi erreichbar sind.

06.04.2011 - 07:56 Uhr

Das ist der row header, das kannst du auch komplett ändern, um es aus zu blenden kannst du RowHeaderWidth auf 0 setzen.

05.04.2011 - 11:19 Uhr

Setz doch einfach RowBackground und AlternatingRowBackground auf Transparent

04.04.2011 - 14:53 Uhr

Das erklärt die Performance

  1. Du hast da ein Grid, Grids sind recht teuer
  2. Du verwendest ein Image ohne Priority Binding, dh beim Tab wechsel muss er alle Bilder neu laden

Schau mal, du sagtest
>> "Ein Treeview kann bis zu 1000 Items enthalten."
dh er erstellt und Recycled 1000 Grids mit Columns und Rows (Wozu eigentlich die Row) mit 1000 Images
das dass an der Leistung zieht bezweifel ich nicht 😉

Probier mal nur Text an zu zeigen, obs dann immernoch so langsam ist, wenn nicht packst du mal dein Grid ohne Image rein, dann hast du schon ein spürbaren unterschied, und die Images sind dann noch das i tüpfelchen 😁

04.04.2011 - 12:10 Uhr

Ich reden von den DataTemplates der TreeViewItems - darum geht es doch...

03.04.2011 - 11:01 Uhr

Der Code mit dem XmlDocument ist nicht fehler sicher

Gegeben:

<Configuration>
  <Properties>
    <Error_Config Error_Port="5000" Error_Example="Example" />
  </Properties>
</Configuration>

public class Settings
{
    public Demo(string fileName)
    {
        _document = XDocument.Load(fileName);

        Defaults = new Defaults();
    }

    private XDocument _document;
    public Defaults Defaults { get; private set; }

    public int Error_Port { get; private set; }
    public int Error_Port { get; private set; }

    public int ReadErrorConfig()
    {
        // Elements da nur 1 tief, ansonsten Descendants
        var propertyElement = _document.Elements("Properties").FirstOrDefault();
        if (propertieElement != null)
        {
            Error_Port = GetChildElementsAttribute(propertyElement, "Error_Config", "Error_Port", Defaults.Error_Port);
            Error_Port = GetChildElementsAttribute(propertyElement, "Error_Config", "Error_Example", Defaults.Error_Example);
        }
    }

    #region Xml Tools
    private static int GetChildElementsAttribute(XContainer container, string childName, stringt attribute, int fallback)
    {
        var value = GetChildElementsAttribute(container, childName, attribute, fallback.ToString());
        int converted = 0;
        if (int.TryParse(value, out converted))
            return converted;
        return fallback;
    }

    private static string GetChildElementsAttribute(XContainer container, string childName, stringt attribute, string fallback)
    {
        var element = container.Elements("Error_Config").FirstOrDefault();
        if (element == null ||
            element.Attribute(attribute) == null)
            return fallback;
        return element.Attribute(attribute).Value;
    }

    // private static string GetChildDescendantsAttribute(..)
    #endregion Xml Tools
}

//Note: Der Code ist nur hier im Forum getippt, es hat keine IDE gesehen, muss also nicht funktioniert oder gar baubar sein ^^

01.04.2011 - 14:33 Uhr

Klar, das geht ganz einfach:

<Style x:Key="MyKey" TargetType="Button">
    <Setter Property="Template">
        <ControlTemplate TargetType="Button">
            <Border x:Name="Display">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <ColorAnimation Duration="0" To="Yellow" Storyboard.TargetProperty="(Background).(GradientStops)[0].Color" Storyboard.TargetName="Display" />
                                <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(Background).(GradientStops)[1].Color" Storyboard.TargetName="Display" />
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Pressed">
                            <Storyboard>
                                <ColorAnimation Duration="0" To="Pink" Storyboard.TargetProperty="(Background).(GradientStops)[0].Color" Storyboard.TargetName="Display" />
                                <ColorAnimation Duration="0" To="WhiteSmoke" Storyboard.TargetProperty="(Background).(GradientStops)[1].Color" Storyboard.TargetName="Display" />
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Border.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Blue" Offset="0.123"/>
                        <GradientStop Color="Green" Offset="0.877"/>
                    </LinearGradientBrush>
                </Border.BorderBrush>
                <ContentPresenter />
            </Border>
        </ControlTemplate>
    </Setter>
</Style>
<Button Content="Blubb" Style="{StaticResource MyKey}" />

Ein Link kann ich nicht bieten, hatte es damals auch nur mit Google und MSDN zusammen gesucht.
Das Beispiel von eben ist eine Kopie aus nem privaten Projekt, habs nur etwas abgeändert. (Copy&Paste Fehler können da sein).
In WPF Machst du es per Trigger, bei Silverlight geht das soweit ich mit bekommen habe nicht, sondern da muss man über den VisualStateManager gehen, und der kann auch nur über Storyboards vorhandenes abändern (In WPF würde man direkt einfach nur eine Farbe setzen).

//Dazu
Sehe gerade, dein Link zeigt genau das selbe 😄

01.04.2011 - 14:22 Uhr

Hmm, dann liegts eventuell an deinen Conotrols.
Du fragtest ob man auch UserControls oder Pages nehmen kann, das geht schon, solltest du aber lassen. Diese Controls haben massig overhead den du vermutlich gar nicht brauchst.

Eventuell bist du zu protzig was die Controls angeht? Zu viele Grids, UserControls on konsorten können schon merklich an der Leistung ziehen.

Wie sieht so ein DataTemplate bei dir aus?

01.04.2011 - 14:18 Uhr

Das erklärt nun auch warum ich bei Automatisch geschloßenen thread problemlos antworten konnte, hatte mich schon gewundert 😄

Bin auch drauf rein gefallen, hab jetzt gerade erst gemerkt was für ein Datum wir haben 😄

01.04.2011 - 11:56 Uhr

Das ist ein Problem der View, nicht des Contents.
Setz den ItemsPanel auf VrtualizedStackPanel. Per default ist es das nicht.

Siehe dazu auch: [Gelöst] Treeview Performance

01.04.2011 - 11:50 Uhr

Das geht, das machst du im Control Style im Template, dort kannst du über den VisualStateManager das aussehen je nach Status setzen.

25.03.2011 - 13:29 Uhr

Was ich schade finde, der runde Button war um Welten schöner anzusehen 😃

Das Argument "Die Leute verstehen es nicht" zieht nicht, denn

  1. Beim ersten Start blinkt er,
  2. Der "Start" Button ist bei Windows 7 auch rund 😉
18.03.2011 - 13:21 Uhr

Man kann auch ein string returnieren, das hatte ich schon öfter gemacht.

Was das Problem ist ist der Pfad im String, dieser sollte der "fullpath" sein.

if (value is Fusballspieler) return "/MyAssembly;component/Resources/Sportarten/Football.ico";

Dann funktioniert [normalerweise] auch mit nem string. Ich persönlich überlasse gerne dem .Net das generieren der Bitmaps.

18.03.2011 - 12:55 Uhr

Ich dacht das liegt daran das MyCSharp nu mit WPF gerendert wird 😁

17.03.2011 - 09:38 Uhr

Wenn sehr viele PCs verwaltet werden sollen sollte man eher über ein SMS dienst nach denken und die PCs über diesen die Updates einspielen. Gerade in großen Netzwerken lädt man Updates nur einmal zentral und gibt das den Clients weiter. Stichwort WSUS 😉

16.03.2011 - 12:59 Uhr

Wozu?

Ein Browser ist zum surfen da, d.h. du hast Internet wenn du ihn installieren willst, wozu also ein Offline Installer?
Die web Installer haben den vorteil das sie immer gleich die neueste Version ziehen.

Wenn du den Offline Installer ziehst und ihn dann für später weg sicherst, musst du dann sowieso noch Patchen nach dem installieren, da installiert man doch lieber gleich die neueste Version mit dem web Installer und fertig.

//Dazu
Bzgl den IE9 warte ich bis es den per Windows update gibt und feddich. Chrome ist mir eh lieber 😁

14.03.2011 - 09:29 Uhr

Ach du meinst das Datum ist Hardcoded? Dann ist natürlich blöd.

Aber was solls.

Umgehung der "Lebenszeit" ist rechtlich sowieso fragwürdig

14.03.2011 - 09:12 Uhr

Über welchen Server bzw über welche Adresse kommuniziert der Reflektor? Man könnte dann ja einfach diese Adresse über die .Hosts Datei dicht machen 😄

Ich muss aber sagen das der ILSpy schon einen sehr guten eindruck macht 😃

13.03.2011 - 13:22 Uhr

Was ist R#?

BTW der 6. Reflektor funktioniert weiterhin, nur auf Updates muss man dann halt verzichten.

12.03.2011 - 12:50 Uhr

Und? Das sagt dir nun was?

  • Hast du die SDK installiert (Ich denke schon, da du ja WinDbg hast)? Eventuell gibt es in den Zusammenhang noch andere Probleme.
  • Hattest du die SP1 Beta installiert und vorher deinstalliert? Das darf man nicht 😉
11.03.2011 - 20:33 Uhr

Hi,

Ich hatte gemerkt das mein WPF Projekt auf x86 stand, die libraries aber auf Any CPU.
Ich habe dann das WPF Projekt auch auf Any CPU gestellt.
Ab dann merkte ich aber das es beim start bis zu 10 Sekunden dauert eh ein (extrem kleines) Fenster angezeigt wird.

Ich sehe im Output das die dlls geladen wurden, dann passiert bis zu 10 Sekunden nichts, und plötzlich ist das Fenster da.
Wenn ich im Fenster etwas aufrufe was neu angezeigt wird, eine Animation, ein MenuItem oder ähnliches, stockt es auch beim ersten verwenden.

Ich habe mir dann gedacht, "ich habe ein x64 System, also bau ich mal direkt auf x64, evtl hat WPF Probleme bei Any CPU".
Nachdem ich auf x64 gebaut habe besserte sich aber gar nichts.
Sobald ich aber das Projekt auf x86 zurück gestellt habe ist das Fenster in Sekundenbruchteilen aufgebaut...

Ist das Normal? Sind WPF Fenster unter x64 tatsächlich langsamer?

Mein System:

  • Windows 7 Home Premium 64Bit
  • 6GB RAM
  • Intel Core i5 M430 @ 2.27
  • Visual Studio Ultimate
  • .Net 4.0 Client Profile

LG

David

07.03.2011 - 11:29 Uhr

Ein CustomControl hat keine Original Farbe. "Original Farben" gibt es nur für .Net Controls bei denen du das Template überschrieben hast, und da ist es dann abhängig vom verwendeten Windows Theme.