最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在WPF中自定義Image控件實(shí)現(xiàn)圖像縮放與平移

 更新時(shí)間:2026年06月02日 08:41:42   作者:加號(hào)3  
本文詳細(xì)講解了在WPF中實(shí)現(xiàn)圖像縮放和平移的核心技術(shù)和最佳實(shí)踐,涵蓋架構(gòu)設(shè)計(jì)、變換矩陣管理、邊界控制策略、慣性滾動(dòng)等及性能優(yōu)化等多個(gè)方面,幫助開(kāi)發(fā)者者構(gòu)建專(zhuān)業(yè)級(jí)體驗(yàn)的自定義圖像控件,需要的朋友可以參考下

在 WPF 應(yīng)用開(kāi)發(fā)中,圖像的交互式瀏覽是一項(xiàng)高頻需求。無(wú)論是醫(yī)學(xué)影像查看、工業(yè)檢測(cè)界面,還是普通圖片瀏覽器,縮放和平移都是最基礎(chǔ)也最核心的交互能力。本文將從架構(gòu)設(shè)計(jì)、坐標(biāo)變換、交互邏輯三個(gè)維度,系統(tǒng)講解如何在 WPF 中構(gòu)建一個(gè)具備專(zhuān)業(yè)級(jí)體驗(yàn)的自定義圖像控件。

一、為什么需要自定義控件

WPF 內(nèi)置的 Image 控件功能單一,僅負(fù)責(zé)將圖像渲染到界面。雖然可以通過(guò) ScaleTransform 和 TranslateTransform 實(shí)現(xiàn)基礎(chǔ)的縮放平移,但在實(shí)際項(xiàng)目中往往面臨以下挑戰(zhàn):

  • 變換原點(diǎn)不一致:縮放時(shí)以鼠標(biāo)位置為中心還是以控件中心為中心,直接決定用戶(hù)體驗(yàn)
  • 邊界約束缺失:圖像縮放過(guò)小或平移出可視區(qū)域后,界面呈現(xiàn)失控狀態(tài)
  • 交互沖突:縮放與平移的手勢(shì)識(shí)別、與外部滾動(dòng)條的協(xié)調(diào)、與選中框等疊加元素的配合
  • 性能瓶頸:大圖像頻繁變換時(shí)的渲染卡頓,以及縮略圖與全圖的切換策略

自定義控件的價(jià)值在于將這些問(wèn)題封裝到控件內(nèi)部,對(duì)外暴露簡(jiǎn)潔的依賴(lài)屬性(如 ZoomLevel、PanOffset),讓業(yè)務(wù)層只需關(guān)注"顯示什么",而非"如何顯示"。

二、核心架構(gòu)設(shè)計(jì)

1. 視覺(jué)樹(shù)結(jié)構(gòu)

一個(gè)健壯的圖像瀏覽控件,視覺(jué)樹(shù)通常包含三層:

  • 底層:圖像層
    承載原始圖像內(nèi)容。使用 ImageBrush 填充一個(gè) Rectangle 或直接使用 Image 元素,配合 RenderTransform 應(yīng)用變換矩陣。選擇 RenderTransform 而非 LayoutTransform 的關(guān)鍵原因在于性能——前者在布局完成后執(zhí)行,不會(huì)觸發(fā)重新測(cè)量和排列。
  • 中層:交互層
    覆蓋在圖像之上的透明面板(如 Canvas 或自定義的 Adorner),負(fù)責(zé)捕獲鼠標(biāo)和觸摸事件。將交互層與圖像層分離,可以避免變換矩陣對(duì)事件坐標(biāo)的干擾,也便于后續(xù)疊加標(biāo)注、測(cè)量線等附加元素。
  • 頂層:裝飾層
    用于顯示當(dāng)前縮放比例、導(dǎo)航縮略圖、操作提示等輔助信息。通常通過(guò) AdornerLayer 實(shí)現(xiàn),保持與主內(nèi)容的解耦。

2. 變換矩陣的統(tǒng)一管理

WPF 中的 MatrixTransform 是管理縮放平移的最佳選擇。相比分別維護(hù) ScaleTransform 和 TranslateTransform,單一矩陣的優(yōu)勢(shì)在于:

  • 組合變換只需一次矩陣乘法,避免多次變換的累積誤差
  • 坐標(biāo)轉(zhuǎn)換(屏幕坐標(biāo) ↔ 圖像坐標(biāo))可以通過(guò)矩陣的逆運(yùn)算精確完成
  • 動(dòng)畫(huà)過(guò)渡時(shí),只需對(duì)矩陣元素進(jìn)行插值,實(shí)現(xiàn)平滑的縮放動(dòng)畫(huà)

控件內(nèi)部維護(hù)一個(gè) Matrix 對(duì)象,任何用戶(hù)操作(滾輪縮放、拖拽平移)都轉(zhuǎn)化為對(duì)該矩陣的更新,再同步到 RenderTransform。

三、縮放邏輯的深度解析

1. 以鼠標(biāo)位置為中心的縮放

這是專(zhuān)業(yè)圖像瀏覽器的標(biāo)準(zhǔn)行為。核心原理是:縮放前后,鼠標(biāo)指針在圖像上的對(duì)應(yīng)物理位置保持不變。
實(shí)現(xiàn)上需要三個(gè)步驟:

  • 獲取鼠標(biāo)當(dāng)前位置相對(duì)于圖像容器的坐標(biāo)
  • 計(jì)算縮放后的新矩陣,使該坐標(biāo)點(diǎn)在新舊矩陣下的映射結(jié)果相同
  • 應(yīng)用新矩陣并刷新顯示
    數(shù)學(xué)上,這等價(jià)于以鼠標(biāo)位置為原點(diǎn)進(jìn)行縮放變換,再補(bǔ)償平移量。這種"錨點(diǎn)縮放"讓用戶(hù)能夠精確放大到感興趣的區(qū)域,而不需要縮放后再手動(dòng)平移調(diào)整。

2. 縮放級(jí)別的離散化與連續(xù)化

兩種策略適用于不同場(chǎng)景:

  • 連續(xù)縮放(如 Photoshop)
    滾輪每轉(zhuǎn)動(dòng)一格,縮放比例按固定步長(zhǎng)(如 1.1 倍)連續(xù)變化。體驗(yàn)流暢,適合精細(xì)調(diào)整,但可能產(chǎn)生非整數(shù)的縮放比例,對(duì)像素級(jí)查看不夠友好。
  • 離散級(jí)別(如地圖應(yīng)用)
    預(yù)定義一組縮放級(jí)別(如 25%、50%、100%、200%),滾輪 操作跳到最近的級(jí)別。適合需要精確比例的場(chǎng)景,但切換時(shí)可能有跳躍感。
    實(shí)際實(shí)現(xiàn)中,可以結(jié)合兩者:滾輪提供連續(xù)縮放,同時(shí)提供快捷鍵直接跳轉(zhuǎn)到 100%(實(shí)際像素)或適應(yīng)窗口等離散級(jí)別。

3. 縮放范圍的邊界控制

必須限制最小和最大縮放比例,防止用戶(hù)操作失控:

  • 最小縮放:通常設(shè)為圖像完全適應(yīng)控件窗口的比例,或略小一些(如 10%)。小于此值時(shí),圖像可能縮成一個(gè)小點(diǎn),失去操作意義。
  • 最大縮放:取決于圖像分辨率和應(yīng)用場(chǎng)景。醫(yī)學(xué)影像可能需要放大到 800% 觀察細(xì)節(jié),而普通圖片瀏覽器 400% 已足夠。
    邊界控制應(yīng)在矩陣計(jì)算階段完成,而非事后修正。即先計(jì)算理論變換矩陣,再將其裁剪到合法范圍內(nèi),最后應(yīng)用。這樣可以避免矩陣"抖動(dòng)"——用戶(hù)快速滾動(dòng)時(shí),縮放比例在邊界附近來(lái)回彈跳。

四、平移邏輯的精細(xì)處理

1. 拖拽平移的坐標(biāo)映射

鼠標(biāo)拖拽時(shí),控件需要區(qū)分"按下了哪個(gè)鍵"和"在哪個(gè)元素上按下"。通常約定:

  • 左鍵拖拽:平移圖像
  • 右鍵拖拽:框選區(qū)域(如有此功能)
  • 中鍵拖拽:部分軟件用作快速平移(與左鍵功能相同,但適合長(zhǎng)時(shí)間拖拽)

拖拽平移的本質(zhì)是:鼠標(biāo)移動(dòng)向量直接映射為圖像的平移向量,再疊加到變換矩陣上。但需要注意,這里的移動(dòng)向量是屏幕像素距離,而矩陣中的平移量是變換后的邏輯距離。由于縮放比例的存在,兩者是線性關(guān)系,但方向相反——鼠標(biāo)向右移動(dòng),圖像應(yīng)向左滾動(dòng),以產(chǎn)生"抓住圖像拖動(dòng)"的物理直覺(jué)。

2. 邊界回彈與留白策略

圖像平移出可視區(qū)域是常見(jiàn)誤操作,控件應(yīng)提供智能約束:

  • 硬邊界(Hard Clamp)
    圖像邊緣不允許超出控件邊界。實(shí)現(xiàn)簡(jiǎn)單,但用戶(hù)體驗(yàn)生硬——當(dāng)圖像放大后,邊緣恰好對(duì)齊邊界時(shí),用戶(hù)可能誤以為已經(jīng)到達(dá)圖像盡頭。
  • 軟邊界(Soft Bounce)
    允許圖像短暫超出邊界,松手后自動(dòng)回彈。類(lèi)似手機(jī)相冊(cè)的體驗(yàn),操作感更自然,但實(shí)現(xiàn)復(fù)雜度增加,需要處理動(dòng)畫(huà)過(guò)渡。
  • 留白邊距(Margin)
    即使圖像完全適應(yīng)窗口,也允許少量平移,使圖像不必始終居中。這在配合其他疊加元素(如側(cè)邊屬性面板)時(shí)特別有用。

3. 慣性滾動(dòng)

對(duì)于觸摸屏或大圖像瀏覽,加入慣性滾動(dòng)能顯著提升體驗(yàn)。鼠標(biāo)/手指松開(kāi)后,圖像繼續(xù)按原有方向減速滑動(dòng),直到停止。實(shí)現(xiàn)上需要:

  • 拖拽過(guò)程中記錄最近幾幀的速度向量
  • 釋放時(shí)根據(jù)末速度啟動(dòng)動(dòng)畫(huà)
  • 動(dòng)畫(huà)每幀按衰減系數(shù)降低速度,同時(shí)檢測(cè)邊界碰撞

WPF 的 CompositionTarget.Rendering 或 Storyboard 均可實(shí)現(xiàn)慣性動(dòng)畫(huà),前者幀率更穩(wěn)定,后者與 XAML 集成更好。

五、代碼實(shí)現(xiàn)

1. 自定義控件界面布局xaml實(shí)現(xiàn)

<UserControl
    x:Class="HalconDemo.ImageUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:HalconDemo"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    d:DesignHeight="1024"
    d:DesignWidth="1920"
    mc:Ignorable="d">
    <Grid>
        <ContentControl
            Name="Part_ImageContainer"
            MaxWidth="1920"
            MaxHeight="1024"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            HorizontalContentAlignment="Stretch"
            VerticalContentAlignment="Stretch"
            ClipToBounds="True"
            Cursor="Hand">
            <Image
                Name="image"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                RenderOptions.BitmapScalingMode="NearestNeighbor">
                <Image.RenderTransform>
                    <TransformGroup x:Name="group">
                        <ScaleTransform x:Name="scaler" />
                        <TranslateTransform x:Name="transer" />
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
        </ContentControl>
    </Grid>
</UserControl>

2. 自定義控件后端代碼cs實(shí)現(xiàn)

/// <summary>
/// ImageUserControl.xaml 的交互邏輯
/// </summary>
public partial class ImageUserControl : UserControl
{
    /// <summary>
    /// 鼠標(biāo)是否按下
    /// </summary>
    private bool mouseDown;


    /// <summary>
    /// 移動(dòng)圖片前,按下鼠標(biāo)左鍵時(shí),鼠標(biāo)相對(duì)于Part_ImageContainer的點(diǎn)
    /// </summary>
    Point moveStart;

    public ImageUserControl()
    {
        InitializeComponent();
    }

    ~ImageUserControl()
    {
        Part_ImageContainer.MouseLeftButtonDown -= ImgMouseLeftButtonDown;
        Part_ImageContainer.MouseMove -= ImgMouseMove;
        Part_ImageContainer.MouseUp -= ImgMouseUp;
    }

    /// <summary>
    /// 初始化加載圖像
    /// </summary>
    /// <param name="filePath">圖像路徑</param>
    /// <param name="IsMove">是否移動(dòng),true是,false否</param>
    public void InitImage(string filePath,bool IsMove = true)
    {
        if (IsMove)
        {
            Part_ImageContainer.MouseLeftButtonDown += ImgMouseLeftButtonDown;
            Part_ImageContainer.MouseMove += ImgMouseMove;
            Part_ImageContainer.MouseUp += ImgMouseUp;
        }
        image.Source = new BitmapImage(new Uri(filePath, UriKind.Absolute));
    }

    private void ImgMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        //嘗試將鼠標(biāo)強(qiáng)制捕獲到此元素
        Part_ImageContainer.CaptureMouse();
        mouseDown = true;
        moveStart = e.GetPosition(Part_ImageContainer);
    }

    private void ImgMouseMove(object sender, MouseEventArgs e)
    {
        var mouseEnd = e.GetPosition(Part_ImageContainer);           // 鼠標(biāo)移動(dòng)時(shí),獲取鼠標(biāo)相對(duì)圖片容器的點(diǎn)
        if (mouseDown)
        {
            if (e.LeftButton == MouseButtonState.Pressed)           // 按下鼠標(biāo)左鍵,移動(dòng)圖片
            {
                DoMove(mouseEnd);
            }
        }
    }

    private void ImgMouseUp(object sender, MouseButtonEventArgs e)
    {
        Part_ImageContainer.ReleaseMouseCapture();
        mouseDown = false;
    }

    private void ImgMouseWheel(object sender, MouseWheelEventArgs e)
    {
        var point = e.GetPosition(image);
        double delta = e.Delta * 0.002;
        DoScale(point, delta);
    }
    /// <summary>
    /// 縮放圖片。最小為0.1倍,最大為30倍
    /// </summary>
    /// <param name="point">相對(duì)于圖片的點(diǎn),以此點(diǎn)為中心縮放</param>
    /// <param name="delta">縮放的倍數(shù)增量</param>
    private void DoScale(Point point, double delta)
    {
        // 限制最大、最小縮放倍數(shù)
        if (scaler.ScaleX + delta < 0.1 || scaler.ScaleX + delta > 30) return;

        scaler.ScaleX += delta;
        scaler.ScaleY += delta;

        transer.X -= point.X * delta;
        transer.Y -= point.Y * delta;
    }

    /// <summary>
    /// 移動(dòng)圖片
    /// </summary>
    /// <param name="moveEndPoint">移動(dòng)圖片的終點(diǎn)(相對(duì)于Part_ImageContainer)</param>
    private void DoMove(Point moveEndPoint)
    {
        // 考慮到旋轉(zhuǎn)的影響,因此將兩個(gè)點(diǎn)轉(zhuǎn)換到Part_Image坐標(biāo)系,計(jì)算x、y的增量
        Point start = Part_ImageContainer.TranslatePoint(moveStart, image);
        Point end = Part_ImageContainer.TranslatePoint(moveEndPoint, image);


        // 判斷一下,如果scale很大的時(shí)候,移動(dòng)會(huì)很遲緩。此時(shí)應(yīng)該將移動(dòng)放大
        if (scaler.ScaleX > 7)
        {
            transer.X += (end.X - start.X) * 4;
            transer.Y += (end.Y - start.Y) * 4;
        }
        else if (scaler.ScaleX > 5)
        {
            transer.X += (end.X - start.X) * 3;
            transer.Y += (end.Y - start.Y) * 3;
        }
        else if (scaler.ScaleX > 3)
        {
            transer.X += (end.X - start.X) * 2;
            transer.Y += (end.Y - start.Y) * 2;
        }
        else if (scaler.ScaleX < 0.5)
        {
            transer.X += (end.X - start.X) * 0.5;
            transer.Y += (end.Y - start.Y) * 0.5;
        }
        else
        {
            transer.X += (end.X - start.X);
            transer.Y += (end.Y - start.Y);
        }
        moveStart = moveEndPoint;

        // 以下代碼,抄的https://blog.csdn.net/weixin_42975610/article/details/113741534

        // W+w > 2*move_x > -((2*scale-1)*w + W)  水平平移限制條件
        // H+h > 2*move_y > -((2*scale-1)*h + H)  垂直平移限制條件

        if (transer.X * 2 > image.ActualWidth + Part_ImageContainer.ActualWidth - 20)
            transer.X = (image.ActualWidth + Part_ImageContainer.ActualWidth - 20) / 2;

        if (-transer.X * 2 > (2 * scaler.ScaleX - 1) * image.ActualWidth + Part_ImageContainer.ActualWidth - 20)
            transer.X = -((scaler.ScaleX - 0.5) * image.ActualWidth + Part_ImageContainer.ActualWidth / 2 - 10);

        if (transer.Y * 2 > image.ActualHeight + Part_ImageContainer.ActualHeight - 20)
            transer.Y = (image.ActualHeight + Part_ImageContainer.ActualHeight - 20) / 2;

        if (-transer.Y * 2 > (2 * scaler.ScaleY - 1) * image.ActualHeight + Part_ImageContainer.ActualHeight - 20)
            transer.Y = -((scaler.ScaleY - 0.5) * image.ActualHeight + Part_ImageContainer.ActualHeight / 2 - 10);
    }

    /// <summary>
    /// 圖像縮放
    /// </summary>
    /// <param name="point">當(dāng)前坐標(biāo)</param>
    /// <param name="scale">縮放倍數(shù)</param>
    public void ImageScale(Point point, double scale)
    {
        DoScale(point, scale);
    }
}

3. 調(diào)用自定義控件

//控件引用
 <Canvas
     x:Name="canvas"
     Grid.Row="1"
     Background="Black">
     <HalconDemo:ImageUserControl
         x:Name="ImageUserControl"
         Grid.Row="1"
         Width="{Binding ElementName=canvas, Path=ActualWidth}"
         Height="{Binding ElementName=canvas, Path=ActualHeight}"
         MouseWheel="ImageUserControl_MouseWheel" />
 </Canvas>
//鼠標(biāo)滾動(dòng)縮放
 private void ImageUserControl_MouseWheel(object sender, MouseWheelEventArgs e)
 {
     var point = e.GetPosition(image);
     double delta = e.Delta * 0.002;
     ImageUserControl.ImageScale(point, delta);
 }

六、性能優(yōu)化要點(diǎn)

1. 大圖像的分級(jí)加載

直接加載一張 100MB 的 TIFF 圖像到 Image 控件,即使只是顯示縮略圖,也會(huì)消耗大量?jī)?nèi)存。優(yōu)化策略:

  • 解碼尺寸控制:使用 BitmapImage.DecodePixelWidth 限制解碼后的像素尺寸,只加載當(dāng)前視圖需要的分辨率
  • 虛擬化:對(duì)于超大圖像(如衛(wèi)星圖、病理切片),采用金字塔分層結(jié)構(gòu),根據(jù)當(dāng)前縮放級(jí)別加載對(duì)應(yīng)層級(jí)的瓦片
  • 異步加載:圖像解碼在后臺(tái)線程完成,避免阻塞 UI

2. 渲染層優(yōu)化

  • 設(shè)置 RenderOptions.BitmapScalingMode 為 NearestNeighbor(放大時(shí)保持像素銳利)或 Fant(縮小時(shí)平滑)
  • 對(duì)靜態(tài)圖像啟用 BitmapCache,將變換后的結(jié)果緩存為位圖,減少每幀重繪
  • 避免在變換過(guò)程中頻繁更新其他 UI 元素,減少布局傳遞

七、工程實(shí)踐

WPF 自定義 Image 控件的縮放與平移實(shí)現(xiàn),核心在于變換矩陣的精確控制與用戶(hù)交互的細(xì)膩映射:

  • 架構(gòu)選擇:根據(jù)復(fù)用需求選擇附加行為、自定義控件或裝飾器方案
  • 坐標(biāo)管理:理清 DIP、圖像坐標(biāo)、變換矩陣的層級(jí)關(guān)系
  • 交互細(xì)節(jié):以光標(biāo)為中心的縮放、邊界約束、慣性動(dòng)畫(huà)提升體驗(yàn)
  • 性能平衡:緩存策略、大圖像虛擬化、GPU 加速應(yīng)對(duì)復(fù)雜場(chǎng)景
  • 工程化:MVVM 集成、狀態(tài)持久化、無(wú)障礙支持完善產(chǎn)品化

八、總結(jié)

WPF 中實(shí)現(xiàn)圖像縮放平移,表面上是變換矩陣的應(yīng)用,實(shí)質(zhì)上是對(duì)坐標(biāo)系、交互模型、渲染性能的系統(tǒng)把控。自定義控件的意義不在于技術(shù)復(fù)雜度,而在于將"圖像如何被觀看"這一交互細(xì)節(jié)封裝起來(lái),讓業(yè)務(wù)代碼保持清晰。

從以鼠標(biāo)為中心的錨點(diǎn)縮放,到邊界約束與慣性滾動(dòng)的手感調(diào)優(yōu),再到與大圖像、觸控、疊加元素的協(xié)同,每一個(gè)環(huán)節(jié)都直接影響最終用戶(hù)體驗(yàn)。在工業(yè)軟件、醫(yī)療影像、地理信息系統(tǒng)等專(zhuān)業(yè)領(lǐng)域,這些細(xì)節(jié)往往決定了產(chǎn)品的可用性邊界。

對(duì)于 WPF 開(kāi)發(fā)者而言,掌握自定義控件的開(kāi)發(fā)范式,不僅能解決圖像瀏覽這一具體問(wèn)題,更能建立起對(duì) WPF 渲染管線、輸入系統(tǒng)和依賴(lài)屬性的深層理解,為構(gòu)建更復(fù)雜的交互界面打下堅(jiān)實(shí)基礎(chǔ)。

以上就是在WPF中自定義Image控件實(shí)現(xiàn)圖像縮放與平移的詳細(xì)內(nèi)容,更多關(guān)于WPF Image圖像縮放與平移的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#串口通訊概念及簡(jiǎn)單的實(shí)現(xiàn)方法

    C#串口通訊概念及簡(jiǎn)單的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于C#串口通訊概念及簡(jiǎn)單的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 詳解C#如何利用TcpListener和TcpClient實(shí)現(xiàn)Tcp通訊

    詳解C#如何利用TcpListener和TcpClient實(shí)現(xiàn)Tcp通訊

    TcpListener 和 TcpClient 是在 System.Net.Sockets.Socket 類(lèi)的基礎(chǔ)上做的進(jìn)一步封裝,使用 GetStream 方法返回網(wǎng)絡(luò)流,下面我們就來(lái)詳細(xì)一下如何使用TcpListener和TcpClient實(shí)現(xiàn)Tcp通訊吧
    2023-12-12
  • C#實(shí)現(xiàn)跨進(jìn)程條件變量的示例代碼

    C#實(shí)現(xiàn)跨進(jìn)程條件變量的示例代碼

    C#提供的多進(jìn)程同步對(duì)象有互斥鎖和信號(hào)量,但是并沒(méi)有條件變量,雖然信號(hào)量條件變量一定程度可以等效,但是具體的使用還是會(huì)有區(qū)別,本文提供了一種條件變量的實(shí)現(xiàn)方法,可以用于進(jìn)程間的同步控制,需要的朋友可以參考下
    2024-07-07
  • C# 多線程學(xué)習(xí)之基礎(chǔ)入門(mén)

    C# 多線程學(xué)習(xí)之基礎(chǔ)入門(mén)

    線程(英語(yǔ):thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。今天小編就帶大家了解一下C#中的多線程,快來(lái)學(xué)習(xí)一下吧
    2021-12-12
  • C#中關(guān)于double.ToString()的用法

    C#中關(guān)于double.ToString()的用法

    這篇文章主要介紹了C#中關(guān)于double.ToString()的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C#實(shí)現(xiàn)讀取被進(jìn)程占用的文件實(shí)現(xiàn)方法

    C#實(shí)現(xiàn)讀取被進(jìn)程占用的文件實(shí)現(xiàn)方法

    這篇文章主要介紹了C#實(shí)現(xiàn)讀取被進(jìn)程占用的文件實(shí)現(xiàn)方法,涉及C#進(jìn)程操作及文件讀取的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • C#的FileInfo類(lèi)實(shí)現(xiàn)文件操作實(shí)例

    C#的FileInfo類(lèi)實(shí)現(xiàn)文件操作實(shí)例

    這篇文章主要介紹了C#的FileInfo類(lèi)實(shí)現(xiàn)文件操作實(shí)例,比較實(shí)用的功能,需要的朋友可以參考下
    2014-07-07
  • C#調(diào)用SQLite的詳細(xì)代碼舉例

    C#調(diào)用SQLite的詳細(xì)代碼舉例

    SQLite是一個(gè)輕量級(jí)、跨平臺(tái)的關(guān)系型數(shù)據(jù)庫(kù),在小型項(xiàng)目中,方便,易用,同時(shí)支持多種開(kāi)發(fā)語(yǔ)言,這篇文章主要給大家介紹了關(guān)于C#調(diào)用SQLite的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • C#簡(jiǎn)易圖片格式轉(zhuǎn)換器實(shí)現(xiàn)方法

    C#簡(jiǎn)易圖片格式轉(zhuǎn)換器實(shí)現(xiàn)方法

    這篇文章主要介紹了C#簡(jiǎn)易圖片格式轉(zhuǎn)換器實(shí)現(xiàn)方法,涉及C#基于WinForm操作圖片的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • C#基礎(chǔ)語(yǔ)法:as 運(yùn)算符使用實(shí)例

    C#基礎(chǔ)語(yǔ)法:as 運(yùn)算符使用實(shí)例

    這篇文章主要介紹了C#基礎(chǔ)語(yǔ)法:as 運(yùn)算符使用實(shí)例,本文給出了類(lèi)、字符串、數(shù)字、浮點(diǎn)數(shù)、null等值的運(yùn)算實(shí)例,需要的朋友可以參考下
    2015-06-06

最新評(píng)論

富锦市| 石河子市| 筠连县| 吉安县| 武宣县| 定兴县| 崇义县| 沂源县| 灵宝市| 邵武市| 金堂县| 潍坊市| 颍上县| 辽宁省| 岳西县| 清河县| 彩票| 绥江县| 政和县| 朝阳区| 边坝县| 大洼县| 满洲里市| 巩留县| 中江县| 阜城县| 綦江县| 玛纳斯县| 敦煌市| 南岸区| 博野县| 章丘市| 体育| 开远市| 延寿县| 潮安县| 浦城县| 渑池县| 崇左市| 千阳县| 景东|