[WPF]常用小撇步

本篇文章記錄筆者在開發WPF時,一些無法直接使用,需要搜尋才會的小技巧,篇幅不大,統一記錄在此,並且不定時更新

讓觸控螢幕可正常滑動的ScrollViewer

正常觸控螢幕使用ScrollViewer時,都只能點擊卷軸才能捲動,無法像手機一樣直覺使用,加上PanningMode="Both"後即可直覺操作

<ScrollViewer PanningMode="Both"></ScrollViewer>

參考 WPF Scrollviewer on touch screen tablet

想要有類似網頁上的超連結樣式,以及點擊效果,可以用以下方式產生

<TextBlock Name="TextBlockWithHyperlink">
    Some text 
    <Hyperlink 
        NavigateUri="http://somesite.com"
        RequestNavigate="Hyperlink_RequestNavigate">
        some site
    </Hyperlink>
    some more text
</TextBlock>

定義點擊事件以及程式動態產生

private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) {
    System.Diagnostics.Process.Start(e.Uri.ToString());
}

TextBlockWithHyperlink.Inlines.Clear();
TextBlockWithHyperlink.Inlines.Add("Some text ");
Hyperlink hyperLink = new Hyperlink() {
    NavigateUri = new Uri("http://somesite.com")
};
hyperLink.Inlines.Add("some site");
hyperLink.RequestNavigate += Hyperlink_RequestNavigate;
TextBlockWithHyperlink.Inlines.Add(hyperLink);
TextBlockWithHyperlink.Inlines.Add(" Some more text");

參考 Add hyperlink to textblock wpf

沒有點擊事件的ItemsControl

需要呈現List類型的資料,可是又不需要像ListBox點選的功能,可以用ItemsControl,預設是垂直顯示,若要水平顯示,需自訂義ItemsControl.ItemsPanel

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

參考 ItemsControl with horizontal orientation

色碼轉換為System.Windows.Midia.Color

var color = (Color)ColorConverter.ConvertFromString("Red or #FF0000");

參考 How do I convert a string like “Red” to a System.Windows.Media.Color?

TextBlock在XAML中如何自行換行

XAML中的內容,使用\n無法正常換行,有2種替代方式

<TextBlock Text="Here is some text. 
 Here is 
 some 
 more."/>
<TextBlock>
  <Run Text="Line1"/>
  <LineBreak />
  <Run Text="Line2"/>
</TextBlock>

參考 programmatic textblock entry with linebreaks

ImageBrush.ImageSource的Binding方式

無法直接綁定url,需要使用BitmapImage的方式

<ImageBrush ImageSource="{Binding PicUrl}"></ImageBrush>
public BitmapImage PicUrl
{
    get => new BitmapImage(new Uri("http://youur/image.jpg", UriKind.Absolute));
}

綁定後更新卻出現跨執行緒問題

明明正常綁定,修改值後,呼叫NotifyPropertyChanged,卻會跳出錯誤

  • 必須在與 DependencyObject 相同的執行緒上建立 DependencySource
  • Must create DependencySource on same Thread as the DependencyObject

而且神奇的是,一個變數可以,另一個卻不行,經過仔細盤查後,發現綁定的class內包含SolidColorBrush變數,是一個freezable的物件,簡單來說,若IsFrozen 為false時,只有建立該物件的執行緒可以存取,我試過即使在Dispatcher.Invoke內呼叫NotifyPropertyChanged,仍會引發InvalidOperationException,解決辦法就是建立SolidColorBrush變數後,執行一次Freeze方法就可以了,所有有繼承Freezable的物件都可能會遇到此問題。

參考

Properties.Settings.Default路徑

儲存設定的功能方便好用,但有時需要測試首次使用,需要刪除,路徑就在

C:\Users\[user]\AppData\Local\Microsoft\專案名稱\

看需求整個資料夾刪除,或者可手動修改特定值,格式是XML,曾經遇過該檔案毀損,導致程式一開啟就Crash,找半天找不到原因,結果就是刪掉搞定,現在想想當時應該要分析檔案深究原因,處理太草率了~

參考 Where is the data for Properties.Settings.Default saved?

取得渲染後的UI元件寬高

UI元件若是不指定寬高的話,主要是根據其內容決定,像是TextBlock,會根據字數多寡來動態決定,如果文字是用程式動態加入,又馬上讀取ActualWidth,值會是0,因為尚未選染到畫面上,需要呼叫Measure() 後再呼叫 Arrange(),此時ActualWidth和ActualHeight就可以取得實際的值了。

參考 how to calculate the textbock height and width in on load if i create textblock from code?

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

Create a website or blog at WordPress.com

向上 ↑

%d 位部落客按了讚: