WPF Notes

作者: Kreiven | 来源:发表于2018-05-08 14:40 被阅读0次

Why is 'StringFormat' malfunctioning?

About Data Type

If you are binding a string value to text property of TextBlock or TextBox, then append StringFormat, it will work.
For example: <TextBlock Text="{Binding StringValue, StringFormat={} I am special: {0}}" />
Otherwise, let's say if there's a object value is bound to text, it won't work at all. In this situation, you need a Converter to solve.

Decimal Type

If you are binding a string value to text property and the StringFormat is like: {}{0:N0}(formatted number), it won't work either. This also won't work in c# code like string.Format("{0:n0}", value)(if value is astring)

Why does my UI text blurry after apply DropShadowEffect?

  • Solution 1: Separate Control which applied DropShadowEffect from your text Control.
  • Solution 2: Add RenderingBias="Quality" attribute to DropShadowEffect. See ref
  • Solution 3: DropShadowEffect may cause performance issue, try SystemDropShadowChrome instead:
    • Add reference to project: PresentationFramework.Aero
    • Add using: xmlns:dropShadow="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"

How to debug codes in design mode?

Here are the steps to debug a control at design time:

Start a second instance of Visual Studio
Attach to the first instance(vs designer is called XDesProc.exe) from the Debug menu
In the second instance, open the source code of your control
Set breakpoints at appropriate locations
In the first VS instance, reload the designer

Note that this technique isn't limited to controls; you can also use it to debug VS extensions, or anything that executes within Visual Studio.

see ref

How to binding control events to commands

<i:Interaction.Triggers>
    <i:EventTrigger EventName="OnLoaded">
        <i:EventTrigger.Actions>
            <i:InvokeCommandAction Command="{Binding MyCommand}"></i:InvokeCommandAction>
        </i:EventTrigger.Actions>
    </i:EventTrigger>
</i:Interaction.Triggers>

How to use async command execute

private async void MyCommandExecute()
{
    IsBusy = true;
    var models = await Task.Run(() =>
    {
        return GetDataFromServer();
    });
    IsBusy = false;
}

or in a better way, encapsulate DoWork method in ViewModelBase:

ViewModelBase.cs
rprc IsBusy;
public async void DoProgressAsync<TResult>(Func<TResult> workFunc, Action<TResult> callbackAction)
{
    IsBusy = true;
    var result = await Task.Run(workFunc);
    callbackAction(result);
    IsBusy = false;
}

Events for Switch TextBlock to TextBox when mousedown

Here is fields and properties in the custom control we need: _isMouseDown; IsEditMode(dependency property)

public override void OnApplyTemplate()
{
    _textblock.PreviewMouseLeftButtonDown += delegate { _isMouseDown = true; };
    _textblockv.PreviewMouseLeftButtonUp += delegate {
        if(_isMouseDown) {
          IsEditMode = true;
          Keyboard.Focus(_textBox);
          _isMouseDown = false;
        }
    };
    _label.GotKeyboardFocus += delegate{
       //same as left button up
    };
    _textBox.LostKeyboardFocus += delegate {
        IsEditMode = false;
    };
}

Simple Loading Ellipse

<ControlTemplate x:Key="LoadingControlTemplate">
        <Ellipse StrokeThickness="2" Width="12" Height="12" RenderTransformOrigin="0.5 0.5" ToolTip="{TemplateBinding ToolTip}" Name="el">
            <Ellipse.Stroke>
                <RadialGradientBrush GradientOrigin="0.2 0" Center="0.5 0.9"  RadiusX="0.75" RadiusY="0.5">
                    <GradientStop Color="Transparent" Offset="1" />
                    <GradientStop Color="White" Offset="0.35" />
                </RadialGradientBrush>
            </Ellipse.Stroke>
            <Ellipse.RenderTransform>
                <RotateTransform Angle="0" />
            </Ellipse.RenderTransform>
        </Ellipse>
        <ControlTemplate.Triggers>
            <Trigger Property="Visibility" Value="Visible">
                <Trigger.EnterActions>
                    <BeginStoryboard Name="ani">
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="(Ellipse.RenderTransform).(RotateTransform.Angle)"
                                             Storyboard.TargetName="el"
                                             To="360" Duration="0:0:0.75" RepeatBehavior="Forever" />
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="ani"/>
                </Trigger.ExitActions>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

Solid color style ProgressBar

for Indeterminate

<!--Please use Foreground as Indicator color-->
<ControlTemplate x:Key="IndeterminateProgressBar" TargetType="{x:Type ProgressBar}" >
    <Grid MinHeight="2" MinWidth="150" Name="TemplateRoot" SnapsToDevicePixels="True" >
        <Rectangle RadiusX="2" RadiusY="2" Fill="Transparent" />
        <Border CornerRadius="0" Margin="1">
            <Border.Background>
                <SolidColorBrush Color="Transparent"/>
            </Border.Background>
        </Border>
        <Border BorderThickness="0" BorderBrush="Transparent" Margin="1">
            <Border.Background>
                <SolidColorBrush Color="Transparent"/>
            </Border.Background>
        </Border>
        <Rectangle Name="PART_Track" Margin="1" />
        <Decorator Name="PART_Indicator" Margin="1" HorizontalAlignment="Left">
            <Grid Name="Foreground">
                <Rectangle Fill="Transparent" Name="Indicator" />
                <Grid Name="Animation" ClipToBounds="True">
                    <Border Name="PART_GlowRect" Width="80"  Margin="0,0,0,0" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}"/>
                </Grid>
                <Grid Name="Overlay">
                </Grid>
            </Grid>
        </Decorator>
        <Border BorderThickness="0" CornerRadius="0" BorderBrush="Transparent" />
    </Grid>
</ControlTemplate>

for Determinate

<!--Please use Foreground as Indicator color, Background as TotalWidth background-->
<ControlTemplate x:Key="DeterminateProgressBar" TargetType="{x:Type ProgressBar}">
    <Grid MinHeight="2" MinWidth="150" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <Border x:Name="PART_Track" BorderThickness="0">
        </Border>
        <Border x:Name="PART_Indicator" BorderThickness="0" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}" Margin="0">
        </Border>
    </Grid>
</ControlTemplate>

Usage

<ProgressBar Template="{StaticResource IndeterminateProgressBar}" IsIndeterminate="True" Foreground="LightBlue" 
              Visibility="{Binding IsRefreshing, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<ProgressBar Template="{StaticResource DeterminateProgressBar}" Minimum="0" Maximum="{Binding ItemCount}" Value="{Binding CurrentItemIndex}" Foreground="Red" Background="Green"
              Visibility="{Binding IsLoadingFinished, Converter={StaticResource BooleanToVisibilityConverter}}"/>

**for 30 seconds pending progress

A little trick using rectangle by scale animation rather than ProgressBar with Timer:

<Style x:Key="PendingProgressRect" TargetType="Rectangle">
        <Setter Property="Height" Value="1"/>
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <ScaleTransform ScaleX="0"></ScaleTransform>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="Visibility" Value="Visible">
                <Trigger.EnterActions>
                    <BeginStoryboard Name="pendingProgressAni">
                        <Storyboard>
                            <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetProperty="RenderTransform.ScaleX"
                                Duration="0:0:30" Timeline.DesiredFrameRate="1">
                                <DiscreteDoubleKeyFrame Value="0.1" KeyTime="0:0:3" />
                                <DiscreteDoubleKeyFrame Value="0.2" KeyTime="0:0:6" />
                                <DiscreteDoubleKeyFrame Value="0.3" KeyTime="0:0:9" />
                                <DiscreteDoubleKeyFrame Value="0.4" KeyTime="0:0:12" />
                                <DiscreteDoubleKeyFrame Value="0.5" KeyTime="0:0:15" />
                                <DiscreteDoubleKeyFrame Value="0.6" KeyTime="0:0:18" />
                                <DiscreteDoubleKeyFrame Value="0.7" KeyTime="0:0:21" />
                                <DiscreteDoubleKeyFrame Value="0.8" KeyTime="0:0:24" />
                                <DiscreteDoubleKeyFrame Value="0.9" KeyTime="0:0:27" />
                                <DiscreteDoubleKeyFrame Value="1.0" KeyTime="0:0:29.7" />
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <RemoveStoryboard BeginStoryboardName="pendingProgressAni"/>
                </Trigger.ExitActions>
            </Trigger>
        </Style.Triggers>
    </Style>

AddSorted to List/Collection

/// <summary>
/// Adds a new item with sorted by comparer in the collection.
/// </summary>
public static void AddSorted<T>(this IList<T> list, T item, IComparer<T> comparer = null)
{
    var comparerPara = comparer;

    if (comparerPara == null)
        comparerPara = Comparer<T>.Default;

    int i = 0;
    while (i < list.Count && comparerPara.Compare(list[i], item) < 0)
    {
        i++;
    }

    //you may want to invoke this on UI thread if context is at background.
    list.Insert(i, item);
}

Then any model which has IComparable<T> implemented will take effect in this extension method.

相关文章

  • WPF Notes

    Why is 'StringFormat' malfunctioning? About Data Type If ...

  • WPF简介

    目录 什么是WPF? WPF的历史? 为什么要用WPF及WPF作用 WPF与winForm区别? 什么是WPF? ...

  • 【WPF】WPF介绍

    一、WPF简介 WPF:WPF即Windows Presentation Foundation,翻译为中文“Win...

  • WPF/C#学习笔记.1:WPF中的布局TabControl,G

    WPF/C#学习笔记.1 WPF中的布局TabControl,Grid与GridSpliter等 WPF布局原则 ...

  • 1. WPF概述

    wpf是什么 wpf(windows presentation foundation)是用于windows的现代图...

  • WPF与WinForm开发有什么区别?

    WPF开发于WinForm之后,从技术发展的角度,WPF比WinForm先进是不容置疑的。我觉得WPF相比于Win...

  • wpf 中的无效绑定

    设置wpf绑定的跟踪级别为high,output中观察wpf的处理流程: 对于一个无效的绑定,wpf尝试了5次,最...

  • WPF入门

    ``` wpf入门 ```

  • Xaml GUI开发的当下.md

    XAML的诞生 Xaml是微软发布WPF时提出的GUI布局描述技术。 为何不用WPF 微软一贯的尿性,WPF已经不...

  • WPF初印象

    一、与WPF结缘 第一次接触WPF是在2012年。学习了WinForm编程之后,了解到WPF这个非常先进的UI框架...

网友评论

    本文标题:WPF Notes

    本文链接:https://www.haomeiwen.com/subject/fftwrftx.html