Я хотів би зробити дві речі на своїй панелі прогресу.
- Змініть зелений колір на червоний.
- Вийміть блоки і зробіть це в одному кольорі.
Будь-яка інформація про ці дві речі, про яку я думаю, як це зробити, буде чудово оцінена!
Дякую.
Я хотів би зробити дві речі на своїй панелі прогресу.
Будь-яка інформація про ці дві речі, про яку я думаю, як це зробити, буде чудово оцінена!
Дякую.
Відповіді:
Оскільки попередні відповіді, здається, не працюють із візуальними стилями. Ймовірно, вам доведеться створити власний клас або розширити індикатор виконання:
public class NewProgressBar : ProgressBar
{
public NewProgressBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
Rectangle rec = e.ClipRectangle;
rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
if(ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
rec.Height = rec.Height - 4;
e.Graphics.FillRectangle(Brushes.Red, 2, 2, rec.Width, rec.Height);
}
}
РЕДАКТУВАТИ: оновлений код, щоб панель виконання використовувала візуальний стиль для фону
Добре, мені знадобився час, щоб прочитати всі відповіді та посилання. Ось що я з них отримав:
Зразок результатів
Прийнята відповідь вимикає візуальні стилі, вона дозволяє встановити колір на будь-що, що завгодно, але результат виглядає просто:
За допомогою наступного методу ви можете отримати щось на зразок цього:
Як
По-перше, включіть це, якщо цього не зробили: using System.Runtime.InteropServices;
По-друге, ви можете або створити цей новий клас, або додати його код до існуючого static
не-загального класу:
public static class ModifyProgressBarColor
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
public static void SetState(this ProgressBar pBar, int state)
{
SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
}
}
Тепер, щоб скористатися ним, просто зателефонуйте:
progressBar1.SetState(2);
Зверніть увагу на другий параметр у SetState, 1 = нормальний (зелений); 2 = помилка (червона); 3 = попередження (жовте).
Сподіваюся, це допоможе!
public const uint PBM_SETSTATE = 0x0410; // 1040
Це версія найменш прийнятого коду без мерехтіння, яку ви можете знайти як відповідь на це запитання. Вся честь плакатам цих фантастичних відповідей. Дякую Дасті, Крісу, Метту та Джошу!
Як і запит "Fueled" в одному з коментарів, мені також потрібна була версія, яка вела себе трохи більше ... професійно. Цей код підтримує стилі, як і в попередньому коді, але додає візуалізацію зображення поза екраном та буферизацію графіки (і належним чином розпоряджається графічним об'єктом).
Результат: все добре, і мерехтіння немає. :)
public class NewProgressBar : ProgressBar
{
public NewProgressBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// None... Helps control the flicker.
}
protected override void OnPaint(PaintEventArgs e)
{
const int inset = 2; // A single inset value to control teh sizing of the inner rect.
using (Image offscreenImage = new Bitmap(this.Width, this.Height))
{
using (Graphics offscreen = Graphics.FromImage(offscreenImage))
{
Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);
rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
if (rect.Width == 0) rect.Width = 1; // Can't draw rec with width of 0.
LinearGradientBrush brush = new LinearGradientBrush(rect, this.BackColor, this.ForeColor, LinearGradientMode.Vertical);
offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
e.Graphics.DrawImage(offscreenImage, 0, 0);
}
}
}
}
У дизайнері вам просто потрібно встановити для властивості ForeColor будь-який колір, який ви хочете. У випадку з червоним для нього є заздалегідь визначений колір.
Для цього в коді (C #) зробіть так:
pgs.ForeColor = Color.Red;
Редагувати : Так, так само, встановіть Стиль на суцільний. У коді, наприклад:
pgs.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
Ще одне редагування: вам також потрібно буде видалити рядок, який читається, Application.EnableVisualStyles()
із вашого Program.cs
(або подібного). Якщо ви не можете цього зробити, оскільки хочете, щоб решта додатків мала візуальні стилі, то я б запропонував розфарбувати елемент керування самостійно або перейти до WPF, оскільки подібні речі з WPF прості. Ви можете знайти підручник з власником, який малює індикатор прогресу на codeplex
Використовуючи відповіді Метта Блейна та Кріса Персічетті, я створив індикатор прогресу, який виглядає дещо приємнішим, дозволяючи нескінченний вибір кольорів (в основному я змінив один рядок у рішенні Метта):
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace QuantumConcepts.Common.Forms.UI.Controls
{
public class ProgressBarEx : ProgressBar
{
public ProgressBarEx()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
LinearGradientBrush brush = null;
Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);
rec.Width = (int)((rec.Width * scaleFactor) - 4);
rec.Height -= 4;
brush = new LinearGradientBrush(rec, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
}
}
}
progressBar.ForeColor = Color.FromArgb(255, 0, 0);
progressBar.BackColor = Color.FromArgb(150, 0, 0);
https://skydrive.live.com/?cid=0EDE5D21BDC5F270&id=EDE5D21BDC5F270%21160&sc=documents#
LinearGradientBrush
зчитування ширини запису як 0. Найпростішим виправленням є не робити "відступ" 4px в коді, а замість цього розмістити його в панель або що - то з прокладкою (якщо ви хочете кордон) і зробити rec.Width = (int)((rec.Width * scaleFactor) - 4)
вrec.Width = (int)(rec.Width * scaleFactor) + 1
Модифікація відповіді Дастібурвелла. (У мене недостатньо представника для редагування.) Як і його відповідь, він працює з увімкненим "Візуальним стилем". Ви можете просто встановити властивість ForeColor на панелі прогресу в будь-якому дизайні.
using System;
using System.Windows.Forms;
using System.Drawing;
public class ProgressBarEx : ProgressBar
{
private SolidBrush brush = null;
public ProgressBarEx()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
if (brush == null || brush.Color != this.ForeColor)
brush = new SolidBrush(this.ForeColor);
Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rec);
rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
rec.Height = rec.Height - 4;
e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
}
}
Я просто поклав це в статичний клас.
const int WM_USER = 0x400;
const int PBM_SETSTATE = WM_USER + 16;
const int PBM_GETSTATE = WM_USER + 17;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public enum ProgressBarStateEnum : int
{
Normal = 1,
Error = 2,
Paused = 3,
}
public static ProgressBarStateEnum GetState(this ProgressBar pBar)
{
return (ProgressBarStateEnum)(int)SendMessage(pBar.Handle, PBM_GETSTATE, IntPtr.Zero, IntPtr.Zero);
}
public static void SetState(this ProgressBar pBar, ProgressBarStateEnum state)
{
SendMessage(pBar.Handle, PBM_SETSTATE, (IntPtr)state, IntPtr.Zero);
}
Сподіваюся, це допоможе,
Марк
Зазвичай панель виконання є або тематичною, або з повагою до колірних уподобань користувача. Отже, для зміни кольору вам потрібно або вимкнути візуальні стилі, і встановити, ForeColor
або намалювати управління самостійно.
Що стосується неперервного стилю, то замість блоків ви можете встановити Style
властивість:
pBar.Style = ProgressBarStyle.Continuous;
РЕДАГУВАТИ
За звуками речей, якими ви користуєтесь темою XP, яка має зелений блок на базі прогресу. Спробуйте перетворити свій стиль інтерфейсу на класичний Windows і протестуйте ще раз, але, можливо, вам доведеться реалізувати власну подію OnPaint, щоб змусити її робити те, що ви хочете, у всіх стилях інтерфейсу користувача
Або, як хтось інший зазначив, вимкніть VisualStyles для вашої програми.
Оригінал
Наскільки мені відомо, візуалізація панелі "Прогрес" відбувається відповідно до вибраного вами стилю теми Windows (win2K, xp, vista)
Ви можете змінити колір, встановивши властивість
ProgressBar.ForeColor
Я не впевнений, що ви можете зробити набагато більше, проте ...
робить якийсь гугл
Є тут стаття з MS KB про створення "плавної" смуги прогресу
спробуйте використати messsage PBM_SETBARCOLOR, який повинен зробити фокус із SendMessage
Для прикладу див. Http://www.vbforums.com/showthread.php?t=248721 .
Всі ці методи не працюють для мене, але цей метод дозволяє змінити його на кольоровий рядок.
Зверніть увагу, що я знайшов цей код десь ще на StackOverflow і трохи змінив його. З тих пір я забув, де я знайшов цей код, і я не можу зв’язати його через те, що так шкодую за це.
Але в будь-якому випадку я сподіваюся, що цей код допомагає комусь, він справді мені допоміг.
private void ProgressBar_MouseDown(object sender, MouseButtonEventArgs e)
{
var converter = new System.Windows.Media.BrushConverter();
var brush = (Brush)converter.ConvertFromString("#FFB6D301");
ProgressBar.Foreground = brush;
}
Там, де використовується назва "ProgressBar", замініть власну назву індикатора прогресу. Ви також можете запустити цю подію за допомогою інших аргументів, просто переконайтеся, що її внутрішні дужки десь.
Зміна Color
іValue
(миттєва зміна)
Покласти using System.Runtime.InteropServices;
зверху ...
Телефонуйте за допомогою ColorBar.SetState(progressBar1, ColorBar.Color.Yellow, myValue);
Я помітив, що якщо ви зміните значення смуги (наскільки вона велика), вона не зміниться, якщо вона має інший колір, ніж зелений за замовчуванням. Я взяв код користувача1032613 і додав опцію Value.
public static class ColorBar
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
public enum Color { None, Green, Red, Yellow }
public static void SetState(this ProgressBar pBar, Color newColor, int newValue)
{
if (pBar.Value == pBar.Minimum) // If it has not been painted yet, paint the whole thing using defualt color...
{ // Max move is instant and this keeps the initial move from going out slowly
pBar.Value = pBar.Maximum; // in wrong color on first painting
SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
}
pBar.Value = newValue;
SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero); // run it out to the correct spot in default
SendMessage(pBar.Handle, 1040, (IntPtr)(int)newColor, IntPtr.Zero); // now turn it the correct color
}
}
pBar.Value = pBar.Maximum;
і SendMessage(pBar.Handle, 1040, (IntPtr)(int)Color.Green, IntPtr.Zero);
всередину умова тіла для прогресу , щоб показати правильний новий колір.
Просто клацніть правою кнопкою миші на своєму проекті в Visual Basic Solution Explorer (де знаходяться ваші файли vb) і виберіть властивості з меню. У вікні, що з’явиться, зніміть прапорець біля пункту «Увімкнути візуальні стилі XP», і тепер, коли ви встановите попередній колір, він повинен працювати зараз.
Јοеу: Цитата: Зазвичай панель виконання є або тематичною, або з повагою до колірних уподобань користувача. Отже, для зміни кольору вам потрібно або вимкнути візуальні стилі, і встановити, ForeColor
або намалювати управління самостійно.
Що стосується неперервного стилю, то замість блоків ви можете встановити Style
властивість:
pBar.Style = ProgressBarStyle.Continuous;
ProgressBarStyle.Continuous проти Blocks марний з увімкненим VistualStyles ...
Блок (и) працюватимуть лише з відключеними візуальними стилями ... що робить все це суперечливим (щодо користувацького кольору прогресу) Якщо відключені візуальні стилі ... панель прогресу повинна бути забарвлена на основі попереднього кольору.
Я використав комбінацію відповіді Вільяма Даніеля (з увімкненими візуальними стилями, тому ForeColor не буде просто плоскою без стилю) та відповіді Баррі (на власний текст на панелі прогресу) з: Як мені розмістити текст на ProgressBar?
Вертикальна смуга вгору вниз для червоного кольору:
using System;
using System.Windows.Forms;
using System.Drawing;
public class VerticalProgressBar : ProgressBar
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= 0x04;
return cp;
}
}
private SolidBrush brush = null;
public VerticalProgressBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
if (brush == null || brush.Color != this.ForeColor)
brush = new SolidBrush(this.ForeColor);
Rectangle rec = new Rectangle(0, 0, this.Width, this.Height);
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawVerticalBar(e.Graphics, rec);
rec.Height = (int)(rec.Height * ((double)Value / Maximum)) - 4;
rec.Width = rec.Width - 4;
e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
}
}
Кольорова панель прогресу VB.Net, яка відповідає візуальним стилям WXP, - це ...
Я розпочав з відповіді від 'user1032613' 17.03.12. Зверніть увагу, що це зараз Модуль, а не клас. Звідти я перетворив код, але потрібно було більше. Зокрема, перетворений код показав функцію DirectCast для перетворення цілого числа 'state' у тип IntPtr, який не працював.
Imports System.Runtime.InteropServices
Public Module ModifyProgressBarColor
Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)> _
Private Function SendMessage(hWnd As IntPtr, Msg As UInteger, w As IntPtr, l As IntPtr) As IntPtr
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Sub SetState(pBar As ProgressBar, state As Integer)
'-- Convert state as integer to type IntPtr
Dim s As IntPtr
Dim y As Integer = state
s = IntPtr.op_Explicit(y)
'-- Modify bar color
SendMessage(pBar.Handle, 1040, s, IntPtr.Zero)
End Sub
End Module
І знову просто викличте це у коді, що використовує цей рядок:
Call ModifyProgressBarColor.SetState(prb, 2)
До речі - я спробував інші кольори - 0, 4, 5 - всі вони просто відображалися зеленим.
Я знаю, що його шлях занадто старий, щоб відповісти зараз. Але все-таки невеликий підхід до відповіді @ Daniel за виправлення проблеми, пов’язаної з відсутністю нульової шкали прогресу. Просто намалюйте Прогрес, лише якщо виявлено, що ширина внутрішнього прямокутника не дорівнює нулю.
Дякуємо всім учасникам.
public class ProgressBarEx : ProgressBar
{
public ProgressBarEx()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent){}
// None... Helps control the flicker.
protected override void OnPaint(PaintEventArgs e)
{
const int inset = 2; // A single inset value to control teh sizing of the inner rect.
using (Image offscreenImage = new Bitmap(this.Width, this.Height))
{
using (Graphics offscreen = Graphics.FromImage(offscreenImage))
{
Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
if (ProgressBarRenderer.IsSupported)
ProgressBarRenderer.DrawHorizontalBar(offscreen, rect);
rect.Inflate(new Size(-inset, -inset)); // Deflate inner rect.
rect.Width = (int)(rect.Width * ((double)this.Value / this.Maximum));
if (rect.Width != 0)
{
LinearGradientBrush brush = new LinearGradientBrush(rect, this.ForeColor, this.BackColor, LinearGradientMode.Vertical);
offscreen.FillRectangle(brush, inset, inset, rect.Width, rect.Height);
e.Graphics.DrawImage(offscreenImage, 0, 0);
offscreenImage.Dispose();
}
}
}
}
}
Я виявив, що це можна зробити, намалювавши прямокутник всередині смуги прогресу, та встановити його ширину відповідно до поточного значення прогресу. Я також додав підтримку прогресу справа наліво. Таким чином вам не потрібно використовувати Image, а оскільки Rectnalge.Inflate не називається, намальований прямокутник менший.
public partial class CFProgressBar : ProgressBar
{
public CFProgressBar()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent) { }
protected override void OnPaint(PaintEventArgs e)
{
double scaleFactor = (((double)Value - (double)Minimum) / ((double)Maximum - (double)Minimum));
int currentWidth = (int)((double)Width * scaleFactor);
Rectangle rect;
if (this.RightToLeftLayout)
{
int currentX = Width - currentWidth;
rect = new Rectangle(currentX, 0, this.Width, this.Height);
}
else
rect = new Rectangle(0, 0, currentWidth, this.Height);
if (rect.Width != 0)
{
SolidBrush sBrush = new SolidBrush(ForeColor);
e.Graphics.FillRectangle(sBrush, rect);
}
}
}
Я думаю, що найпростіші рішення з усіх, це лише швидке виправлення, але ви можете видалити, прокоментувати Application.EnableVisualStyles () з Program.cs, або, як би ви не назвали свою частину, що містить функцію Main. Після цього ви можете вільно змінювати колір з індикатора виконання за допомогою progressBar.ForeColor = Color.TheColorYouDesire;
static void Main()
{
//Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
Редагувати: у двох дрібницях мені знадобилося запустити vs і перевірити синтаксис, на який мене побили, набагато кращими відповідями. я люблю цей сайт.
progressBar1 = new ProgressBar();
progressBar1.ForeColor = Color.Red;