Is any way to change the background of the thumb of Trackbar? I use C# winform.
Only the background of the Trackbar can be changed, so how can I change or set something in the thumb?
Any answer appreciated.
I saw the project:
http://www.codeproject.com/Articles/7974/A-variation-on-the-default-TrackBar
And add the Picture of it to let user choose:
/// <summary>
/// Set Image of Trackbar's thumb
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
[Description("Set the picture of the thumb")]
[Category("Image")]
public Image Picture
{
set
{
myPic = value;
}
get { return myPic; }
}
And use TextureBrush to let the picture People shoose be an ImageBrush:
TextureBrush newBrush = new TextureBrush(myPic);
if (myPic != null)
{
g.FillRegion(newBrush, new Region(PaintPath));
newBrush.Dispose();
}
else
{
g.FillRegion(bgBrush, new Region(PaintPath));
bgBrush.Dispose();
}
There is only one problem that the imagebrush is tile style,
if I let it not a tile style, it may resolve my questrion.
Related
Is there a way to smoothly animate a ScrollViewers vertical offset in Windows Phone 8.1 Runtime?
I have tried using the ScrollViewer.ChangeView() method and the change of vertical offset is not animated no matter if I set the disableAnimation parameter to true or false.
For example: myScrollViewer.ChangeView(null, myScrollViewer.VerticalOffset + p, null, false);
The offset is changed without animation.
I also tried using a vertical offset mediator:
/// <summary>
/// Mediator that forwards Offset property changes on to a ScrollViewer
/// instance to enable the animation of Horizontal/VerticalOffset.
/// </summary>
public sealed class ScrollViewerOffsetMediator : FrameworkElement
{
/// <summary>
/// ScrollViewer instance to forward Offset changes on to.
/// </summary>
public ScrollViewer ScrollViewer
{
get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
set { SetValue(ScrollViewerProperty, value); }
}
public static readonly DependencyProperty ScrollViewerProperty =
DependencyProperty.Register("ScrollViewer",
typeof(ScrollViewer),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(null, OnScrollViewerChanged));
private static void OnScrollViewerChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
var scrollViewer = (ScrollViewer)(e.NewValue);
if (null != scrollViewer)
{
scrollViewer.ScrollToVerticalOffset(mediator.VerticalOffset);
}
}
/// <summary>
/// VerticalOffset property to forward to the ScrollViewer.
/// </summary>
public double VerticalOffset
{
get { return (double)GetValue(VerticalOffsetProperty); }
set { SetValue(VerticalOffsetProperty, value); }
}
public static readonly DependencyProperty VerticalOffsetProperty =
DependencyProperty.Register("VerticalOffset",
typeof(double),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(0.0, OnVerticalOffsetChanged));
public static void OnVerticalOffsetChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
if (null != mediator.ScrollViewer)
{
mediator.ScrollViewer.ScrollToVerticalOffset((double)(e.NewValue));
}
}
/// <summary>
/// Multiplier for ScrollableHeight property to forward to the ScrollViewer.
/// </summary>
/// <remarks>
/// 0.0 means "scrolled to top"; 1.0 means "scrolled to bottom".
/// </remarks>
public double ScrollableHeightMultiplier
{
get { return (double)GetValue(ScrollableHeightMultiplierProperty); }
set { SetValue(ScrollableHeightMultiplierProperty, value); }
}
public static readonly DependencyProperty ScrollableHeightMultiplierProperty =
DependencyProperty.Register("ScrollableHeightMultiplier",
typeof(double),
typeof(ScrollViewerOffsetMediator),
new PropertyMetadata(0.0, OnScrollableHeightMultiplierChanged));
public static void OnScrollableHeightMultiplierChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var mediator = (ScrollViewerOffsetMediator)o;
var scrollViewer = mediator.ScrollViewer;
if (null != scrollViewer)
{
scrollViewer.ScrollToVerticalOffset((double)(e.NewValue) * scrollViewer.ScrollableHeight);
}
}
}
and I can animate the VerticalOffset property with DoubleAnimation:
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
da.EnableDependentAnimation = true;
da.From = Mediator.ScrollViewer.VerticalOffset;
da.To = da.From + p;
da.Duration = new Duration(TimeSpan.FromMilliseconds(300));
da.EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut };
Storyboard.SetTarget(da, Mediator);
Storyboard.SetTargetProperty(da, "(Mediator.VerticalOffset)");
sb.Children.Add(da);
sb.Begin();
Mediator is declared in XAML.
But this animation is not smooth on my device (Lumia 930).
You should stick with ChangeView for scrolling animations regardless of whether data virtualization is on or not.
Without seeing your code where the ChangeView doesn't work, it's a bit hard to guess what's really going on but there are a couple of things that you can try.
First approach is to add a Task.Delay(1) before calling ChangeView, just to give the OS some time to finish off other concurrent UI tasks.
await Task.Delay(1);
scrollViewer.ChangeView(null, scrollViewer.ScrollableHeight, null, false);
The second approach is a bit more complex. What I've noticed is that, when you have many complex items in the ListView, the scrolling animation from the first item to the last (from the ChangeView method) isn't very smooth at all.
This is because the ListView first needs to realize/render many items along the way due to data virtualization and then does the animated scrolling. Not very efficient IMHO.
What I came up with is this - First, use a non-animated ListView.ScrollIntoView to scroll to the last item just to get it realized. Then, call ChangeView to move the offset up to a size of the ActualHeight * 2 of the ListView with animation disabled (you can change it to whatever size you want based on your app's scrolling experience). Finally, call ChangeView again to scroll back to the end, with animation this time. Doing this will give a much better scrolling experience 'cause the scrolling distance is just the ActualHeight of the ListView.
Keep in mind that when the item you want to scroll to is already realized on the UI, you don't want to do anything above. You simply just calculate the distance between this item and the top of the ScrollViewer and call ChangeView to scroll to it.
I already wrapped the logic above in this answer's Update 2 section (thanks to this question I realized my initial answer doesn't work when virtualization is on :p). Let me know how you go.
I think that question has already been answered here:
Animated (Smooth) scrolling on ScrollViewer
There is also the WinRT XAML Toolki, which provides "a way to scroll a ScrollViewer to specified offset with animation":
http://winrtxamltoolkit.codeplex.com/
With ScrollToVerticalOffset deprecated/obsolete in newer builds of Windows 10 (leaving the ScrollViewOffSetMediator extension control no longer working), and the new ChangeView method not actually providing smooth or controllable animation, a new solution is needed. Please see my answer here which allows one to smoothly animate and zoom the ScrollViewer and its contents to any desired position, regardless of where the application's end user has the scrollbars initially positioned:
How to scroll to element in UWP
I believe this article is what you're looking for and it seems the method he used is working for you.
Quick Way:
Add offset dependency parameter manually to scrollviewer.
Duplicate your scrollviewer
Use an animator.
I have a UIPopoverController that I am using and I have two buttons each displays a popup when clicked. However, I do not want the popup to be displayed at the same time - meaning I do not want the user to be able to press the one button and while the popup is displayed be able to press the other button. It seems like I have tried everything - disabling the user interaction on the buttons, hiding the view behind the pop up, using passthrough views for the pop and more. None of it works! The disabling of the user interaction seems to work for the most part but then stops disallowing the user to interact with the button and causes the application to crash...
popupView.PassthroughViews = new UIView[]{this.View.Superview, this.View, this.Gray}; //gray is another view that sits under the view that calls the popup
this.View.UserInteractionEnabled = false;
this.PositiveMeterBtn.UserInteractionEnabled = false;
this.View.Hidden = true;
My UIPopoverController is declared at the class level and I have even done code like this:
if(popupView != null)
return;
I still get multiple popups. I am using mono touch/xamarin - is this a bug with xamarin or an ios issue? Am I handling this in the correct manner?
I haven't worked with Xamarin before, but what's worked for me in native Objective-C is
[controller setModalInPopover:YES];
where controller is the view controller displayed within the popover.
From the UIViewController class reference:
#property(nonatomic, readwrite, getter=isModalInPopover) BOOL modalInPopover
The default value of this property is NO. Setting it to YES causes an owning popover controller to disallow interactions outside this view controller while it is displayed.
You can either make the popover modal but if it doesn't contain content that is meant to be modal, you shouldn't block the user.
Usually the better option is to make two helper methods and place them for instance in your app delegate. The methods take care that an existing popover is dismissed if another one is to be shown. This way you will have a maximum of on UIPopoverController and don't have to worry about dismissal.
/// <summary>
/// Shows a popover.
/// </summary>
/// <param name='controllerToShow'>the controller to show in the popover</param>
/// <param name='showFromRect'>the rectangle to present the popover from. Not used if showFromItem is specified.</param>
/// <param name='showInView'>the view the popover is hosted in</param>
/// <param name='showFromItem'>the bar button item the popover gets presented from.</param>
/// <param name='popoverContentSize'>the content size of the popover</param>
/// <param name='animated'>If set to <c>true</c>, animated the popover</param>
/// <param name='arrowDirection'>the allowed arrow directions</param>
/// <param name='onDismiss'>callback if the popover gets dismissed. Careful that the object that owns the callback doesn't outlive the popover controller to prevent uncollectable memory.</param>
public static void ShowPopover(UIViewController controllerToShow, RectangleF showFromRect, UIView showInView, UIBarButtonItem showFromItem, SizeF popoverContentSize, bool animated = true, UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirection.Any, EventHandler onDismiss = null)
{
if(AppDelegateBase.popoverController != null)
{
AppDelegateBase.DismissPopover(false);
}
if(showFromItem == null && showFromRect.IsEmpty)
{
// Nothing to attach the popover to.
return;
}
popoverController = new UIPopoverController(controllerToShow);
if(!popoverContentSize.IsEmpty)
{
popoverController.SetPopoverContentSize(popoverContentSize, false);
}
if(onDismiss != null)
{
popoverController.DidDismiss += onDismiss;
}
// Send a notification that a popover will be presented.
NSNotificationCenter.DefaultCenter.PostNotificationName("WillPresentPopover", popoverController);
if(showFromItem != null)
{
popoverController.PresentFromBarButtonItem(showFromItem, arrowDirection, animated);
}
else
{
popoverController.PresentFromRect(showFromRect, showInView, arrowDirection, animated );
}
}
/// <summary>
/// Dismisses the popover presented using ShowPopover().
/// </summary>
/// <param name='animated'>If set to <c>true</c>, animates the dismissal</param>
public static void DismissPopover(bool animated = false)
{
if(popoverController != null)
{
popoverController.Dismiss(animated);
}
AppDelegateBase.popoverController = null;
}
private static UIPopoverController popoverController;
One thing you might try is using the method
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
And in that method check if one of your popover view controller's is on screen.
if (popupView.view.window) {
return NO;
} else {
return YES;
}
On a ZedGraph pane, it is possible to set a CurveItem as "selected".
zedGraphControl.GraphPane.CurveList[0].IsSelected = true;
zedGraphControl.Refresh();
This will change its color to Color.Gray as far as I can see.
Is it possible to change this selected-state color?
I don't know of such a property but you can accomplish this by manually overriding the MouseClick event of the ZedGraphControl and set the color of the "selected" CurveItem, something like:
private void zedGraphControl1_MouseClick(object sender, MouseEventArgs e)
{
foreach (var curve in zedGraphControl1.GraphPane.CurveList)
{
curve.Color = Color.Black;
}
CurveItem nearestItem;
int nearestPoint;
zedGraphControl1.GraphPane.FindNearestPoint(e.Location, out nearestItem, out nearestPoint);
if (nearestItem != null)
{
nearestItem.Color = Color.Red;
}
zedGraphControl1.Refresh();
}
UPDATE: Looking at the source code of http://www.opensourcejavaphp.net/csharp/zedgraph/Line.cs.html and http://www.opensourcejavaphp.net/csharp/zedgraph/Selection.cs.html it seems that Line.DrawCurve is using static property Selection.Line. Without modifying source it would be hard to change this behaviour.
Part of Line.cs:
public void DrawCurve( Graphics g, GraphPane pane, CurveItem curve, float scaleFactor )
{
Line source = this;
if ( curve.IsSelected )
source = Selection.Line;
Selection.cs:
/// The <see cref="Line" /> type to be used for drawing "selected"
/// <see cref="LineItem" /> and <see cref="StickItem" /> types
/// </summary>
public static Line Line = new Line( Color.Gray );
The selected line is a static property, but NOT read-only. One can change the format by resetting the Selection.Line property:
public Form1()
{
InitializeComponent();
ZedGraph.Selection.Line.Width = 3;
ZedGraph.Selection.Line.Color = Color.Red;
...
}
After resetting the selection line, all selected lines will draw as specified.
I want to change the color of the items that are chedked in the CheckedListBox in C# WindowsForms.
Can any one help me to solve this problem!
This should get you started. I've subclassed a CheckedListBox and overridden the drawing event. The result is all checked items in the list are drawn with a red background.
From playing around with this, if you want the area behind the checkbox to be a different colour as well, use e.Graphics.FillRectangle before calling base.OnDrawItem.
class ColouredCheckedListBox : CheckedListBox
{
protected override void OnDrawItem(DrawItemEventArgs e)
{
DrawItemEventArgs e2 =
new DrawItemEventArgs
(
e.Graphics,
e.Font,
new Rectangle(e.Bounds.Location, e.Bounds.Size),
e.Index,
e.State,
e.ForeColor,
this.CheckedIndices.Contains(e.Index) ? Color.Red : SystemColors.Window
);
base.OnDrawItem(e2);
}
}
Thanks Jon that got me on the right path as I had the same desire: to have the item's text color be different for each of the 3 states of the checkbox.
I came up with this subclass of the CheckedListBox. It changes the items text, not the background color. It lets the 3 colors be set by the user at design time or in code of course.
It also fixes a problem I had where I got an error when viewing the control in the designer. I also had to overcome a problem I think would have happened in your solution where if the item is selected the base.OnDrawItem method obliterates the color choices set in the overridden OnDrawItem method. I did this at the expense of the selected item no longer having a colored background by removing the part of e.State that says it is selected so that in the base.OnDrawItem it is not made to be a selected item look and feel. This is ok though I think since the user will see the focus rectangle still which indicates which is selected.
Hopefully this may be useful to others. I didn't find much for a cohesive solution (even just a complete OnDrawItem method) when looking on the net.
using System;
using System.Windows.Forms;
using System.Drawing;
namespace MyNameSpace
{
/// <summary>
/// This is a CheckedListBox that allows the item's text color to be different for each of the 3 states of the corresponding checkbox's value.
/// Like the base CheckedListBox control, you must handle setting of the indeterminate checkbox state yourself.
/// Note also that this control doesn't allow highlighting of the selected item since that obscures the item's special text color which has the special meaning. But
/// the selected item is still known to the user by the focus rectangle it will have surrounding it, like usual.
/// </summary>
class ColorCodedCheckedListBox : CheckedListBox
{
public Color UncheckedColor { get; set; }
public Color CheckedColor { get; set; }
public Color IndeterminateColor { get; set; }
/// <summary>
/// Parameterless Constructor
/// </summary>
public ColorCodedCheckedListBox()
{
UncheckedColor = Color.Green;
CheckedColor = Color.Red;
IndeterminateColor = Color.Orange;
}
/// <summary>
/// Constructor that allows setting of item colors when checkbox has one of 3 states.
/// </summary>
/// <param name="uncheckedColor">The text color of the items that are unchecked.</param>
/// <param name="checkedColor">The text color of the items that are checked.</param>
/// <param name="indeterminateColor">The text color of the items that are indeterminate.</param>
public ColorCodedCheckedListBox(Color uncheckedColor, Color checkedColor, Color indeterminateColor)
{
UncheckedColor = uncheckedColor;
CheckedColor = checkedColor;
IndeterminateColor = indeterminateColor;
}
/// <summary>
/// Overriden draw method that doesn't allow highlighting of the selected item since that obscures the item's text color which has desired meaning. But the
/// selected item is still known to the user by the focus rectangle being displayed.
/// </summary>
/// <param name="e"></param>
protected override void OnDrawItem(DrawItemEventArgs e)
{
if (this.DesignMode)
{
base.OnDrawItem(e);
}
else
{
Color textColor = this.GetItemCheckState(e.Index) == CheckState.Unchecked ? UncheckedColor : (this.GetItemCheckState(e.Index) == CheckState.Checked ? CheckedColor : IndeterminateColor);
DrawItemEventArgs e2 = new DrawItemEventArgs
(e.Graphics,
e.Font,
new Rectangle(e.Bounds.Location, e.Bounds.Size),
e.Index,
(e.State & DrawItemState.Focus) == DrawItemState.Focus ? DrawItemState.Focus : DrawItemState.None, /* Remove 'selected' state so that the base.OnDrawItem doesn't obliterate the work we are doing here. */
textColor,
this.BackColor);
base.OnDrawItem(e2);
}
}
}
}
I need an Image that is grayed out when disabled (IsEnabled=False). A grayed out version of the image can be produced by reading the BitmapImage into a FormatConvertedBitmap which is shown here.
I have been able to get this working with a UserControl but now I would like the same behavior in a specialized Image class for more flexibility. I don't care if this is implemented in XAML, code-behind or both, but it needs to be a subclass of Image.
The usage could be:
<DisableableImage Source="Images/image1.png" />
<DisableableImage Source="Images/image1.png" IsEnabled="False" />
<!-- Since IsEnabled is inherited down the tree,
the image will be grayed out like the rest of the button -->
<Button IsEnabled="False">
<StackPanel Orientation="Horizontal">
<TextBlock>OK</TextBlock>
<DisableableImage Source="Images/ok.png" />
</StackPanel>
</Button>
Have a look at this link
EDIT:
Or this one (all you need is the AutoGreyableImage class)
I made a little comparison based on the following solutions.
The approaches in the link provided by the OP
The links provided by Thomas Levesque
AutoDisabledImage
AutoGreyableImage
Greyscale Effect
Since I already had a licens for the Infragistics Net Advantage for WPF it was easy to try it out
Here is the result
So the best approach depends on what results you are after. As for me, I think the result produced by AutoDisabledImage from Infragistics is too bright, AutoGreyableImage does a pretty good job (Identical result to Approach 1 (OP link)) and GreyscaleEffect produces the best result.
if you use this a lot consider creating a custom Effect introduced with .NET 3.5 SP1 (not bitmapeffect) to render such an operation on your GPU. this effect can then be easily controlled by triggers.
More complete version of the AutoGreyableImage by Thomas Lebrun. For anyone interested, I started using Thomas Lebruns class and ran into a couple of nullreference exceptions, as well as finding out that an image would not be disabled if the isEnabled property was set first and the source set after.
So here's the class that finally did the trick for me. À propos, you can of course add the matter of opacity into this, but I decided to leave that up to the xaml around the image.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Windows.Media;
namespace MyDisabledImages
{
/// <summary>
/// Class used to have an image that is able to be gray when the control is not enabled.
/// Based on the version by Thomas LEBRUN (http://blogs.developpeur.org/tom)
/// </summary>
public class AutoGreyableImage : Image
{
/// <summary>
/// Initializes a new instance of the <see cref="AutoGreyableImage"/> class.
/// </summary>
static AutoGreyableImage()
{
// Override the metadata of the IsEnabled and Source property.
IsEnabledProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAutoGreyScaleImageIsEnabledPropertyChanged)));
SourceProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnAutoGreyScaleImageSourcePropertyChanged)));
}
protected static AutoGreyableImage GetImageWithSource(DependencyObject source)
{
var image = source as AutoGreyableImage;
if (image == null)
return null;
if (image.Source == null)
return null;
return image;
}
/// <summary>
/// Called when [auto grey scale image source property changed].
/// </summary>
/// <param name="source">The source.</param>
/// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
protected static void OnAutoGreyScaleImageSourcePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs ars)
{
AutoGreyableImage image = GetImageWithSource(source);
if (image != null)
ApplyGreyScaleImage(image, image.IsEnabled);
}
/// <summary>
/// Called when [auto grey scale image is enabled property changed].
/// </summary>
/// <param name="source">The source.</param>
/// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
protected static void OnAutoGreyScaleImageIsEnabledPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
{
AutoGreyableImage image = GetImageWithSource(source);
if (image != null)
{
var isEnabled = Convert.ToBoolean(args.NewValue);
ApplyGreyScaleImage(image, isEnabled);
}
}
protected static void ApplyGreyScaleImage(AutoGreyableImage autoGreyScaleImg, Boolean isEnabled)
{
try
{
if (!isEnabled)
{
BitmapSource bitmapImage = null;
if (autoGreyScaleImg.Source is FormatConvertedBitmap)
{
// Already grey !
return;
}
else if (autoGreyScaleImg.Source is BitmapSource)
{
bitmapImage = (BitmapSource)autoGreyScaleImg.Source;
}
else // trying string
{
bitmapImage = new BitmapImage(new Uri(autoGreyScaleImg.Source.ToString()));
}
FormatConvertedBitmap conv = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0);
autoGreyScaleImg.Source = conv;
// Create Opacity Mask for greyscale image as FormatConvertedBitmap does not keep transparency info
autoGreyScaleImg.OpacityMask = new ImageBrush(((FormatConvertedBitmap)autoGreyScaleImg.Source).Source); //equivalent to new ImageBrush(bitmapImage)
}
else
{
if (autoGreyScaleImg.Source is FormatConvertedBitmap)
{
autoGreyScaleImg.Source = ((FormatConvertedBitmap)autoGreyScaleImg.Source).Source;
}
else if (autoGreyScaleImg.Source is BitmapSource)
{
// Should be full color already.
return;
}
// Reset the Opcity Mask
autoGreyScaleImg.OpacityMask = null;
}
}
catch (Exception)
{
// nothin'
}
}
}
}
Create a DisableableImage class that is a typical WPF control. Inside, place two elements: the image, and a rectangle that appears only when the control is disabled. The rectangle should be the same width and height as the image, and it should overlay the image. With a color of gray and an alpha of somewhere around 40%, you should get an effect similar to actually graying out the image -- without all the effort to actually modify the image itself.