WPF Notes

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.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乖坠,一起剝皮案震驚了整個(gè)濱河市正卧,隨后出現(xiàn)的幾起案子罩息,更是在濱河造成了極大的恐慌战转,老刑警劉巖院水,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掘而,居然都是意外死亡谆趾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門嫁盲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篓叶,“玉大人,你說我怎么就攤上這事「淄校” “怎么了左敌?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長俐镐。 經(jīng)常有香客問我矫限,道長,這世上最難降的妖魔是什么佩抹? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任叼风,我火速辦了婚禮,結(jié)果婚禮上匹摇,老公的妹妹穿的比我還像新娘咬扇。我一直安慰自己甲葬,他們只是感情好廊勃,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著经窖,像睡著了一般坡垫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上画侣,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天冰悠,我揣著相機(jī)與錄音,去河邊找鬼配乱。 笑死溉卓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搬泥。 我是一名探鬼主播桑寨,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忿檩!你這毒婦竟也來了尉尾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤燥透,失蹤者是張志新(化名)和其女友劉穎沙咏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體班套,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肢藐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吱韭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窖壕。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞻讽,到底是詐尸還是另有隱情鸳吸,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布速勇,位于F島的核電站晌砾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏烦磁。R本人自食惡果不足惜养匈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望都伪。 院中可真熱鬧呕乎,春花似錦、人聲如沸陨晶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽先誉。三九已至湿刽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間褐耳,已是汗流浹背诈闺。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铃芦,地道東北人雅镊。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像刃滓,于是被迫代替她去往敵國和親仁烹。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容