For debugging purposes I'd like to set a BitmapImage's Name property. Unfortunately it doesn't exit. Is there any way to identify a specific BitmapImage when setting a breakpoint? In Winforms, all Controls have a Name property, and even if they didn't, we could use the Tag property. For BitmapImage, on the other hand, I can't find anything comparable.
To clarify: I need something defining the BitmapImage itself, not the variable pointing to it, so that if I have bi2 = bi1 - I can check if bi2 is this BitmapImage.
You can use x:Name to define a name of any object in XAML. Then you can use it for example for the debugging purposes.
<Image>
<Image.Source>
<BitmapImage x:Name="MyBitmapImage"/>
</Image.Source>
</Image>
Related
Is it possible to define a GridLength as XAML resources in a ResourceDictionary setting the length value using another StaticResource?
What I'm trying to achieve is something like this:
<System:Double x:Key="MyValue">8</System:Double>
<Thickness x:Key="MyThickness"
Bottom="{StaticResource MyValue}"
Left="{StaticResource MyValue}"
Right="{StaticResource MyValue}"
Top="{StaticResource MyValue}" />
<GridLength x:Key="MyGridLength">{StaticResource MyValue}</GridLength>
Is there a way to do it?
Thank you very much!
I think there is no way to do that exactly like you want to. If you pass any string inside - it will be passed to GridLengthConverter directly and not parsed (so StaticResource etc are ignored). If you will pass xml inside it will be interpreted as content, and GridLength does not support direct content.
So most reasonable option is just duplicate "8" and put MyGridLength near MyValue. Otherwise - move both to static properties (but there you will have only one field with value of 8, so no duplication) and reference via {x:Static}
i have a image control in wpf like this
<Image x:Name="Img" Source="{Binding IsAsync=True}" />
i set the image by fetching from a url like this
Img.DataContext = ImageUrl;
it shows fine and when i want to clear it i just use
Img.DataContext=null;
for the same control i have a browse button as well to select the image from local path like this
BitmapImage image = new BitmapImage(new Uri(path));
Img.Source=image;
now i want to clear that as well so i do
Img.Source=null;
after that the control wont show the image from url only local images can be opened
Edit: probably i need to set the binding again after making source to null, not sure how to do that
You are abusing bindings horribly. Please stop.
<Image x:Name="Img" Source="{Binding IsAsync=True}" />
Says "Bind to the data context", which isn't all that great. Bind to a property of your view model, something like:
<Image x:Name="Img" Source="{Binding Path=ImageLocation, IsAsync=True}" />
And then only ever change the image using ImageLocation. At the very least, only set it via the DataContext.
Once you set the source to a binding, you should never be changing it via code-behind. Period. Do that, and your problem will "magically" disappear, as you are doing it the right way now.
To clear image control, clear image url.
e.g imgControlName.ImageUrl = "";
I have two .png files added to my resources which I need to access their Uri when doing binding.
My xaml code is as followed:
<Grid>
<Image>
<Image.Source>
<BitmapImage DecodePixelWidth="10" UriSource="{Binding Path=ImagePath}"/>
</Image.Source>
</Image>
</Grid>
and the binding code using ImagePath is:
ImagePath = resultInBinary.StartsWith("1") ? Properties.Resources.LedGreen : Properties.Resources.ledRed;
However
Properties.Resources.LedGreen
returns a Bitmap instead of String containing the Uri of that particular image.
I just want to know how to extract that value without a need to address a path of the image in the directory that it's stored. (Which honestly I am not sure is a right thing to do as I couldn't find any similar situation on the net).
Please let me know if there is even a preferred method to the one I am trying to use if available.
In a WPF application you would usually not store images in Properties/Resources.resx and access them by means of the Properties.Resources class.
Instead you just add the image files to your Visual Studio project as regular files, perhaps in a folder named "Images" or the like. Then you would set their Build Action to Resource, which is done in the Properties window. You get there e.g. by right-clicking the image file and select the Properties menu item. Note that the default value of the Build Action should be Resource for image files anyways.
In order to access these image resources from code you would then use a Pack URI. With the above folder name "Images" and an image file named "LedGreen.png", creating such an URI would look like this:
var uri = new Uri("pack://application:,,,/Images/LedGreen.png");
So you could perhaps declare your property to be of type Uri:
public Uri ImageUri { get; set; } // omitted INotifyPropertyChanged implementation
and set it like this:
ImageUri = resultInBinary.StartsWith("1")
? new Uri("pack://application:,,,/Images/LedGreen.png")
: new Uri("pack://application:,,,/Images/LedRed.png");
Finally your XAML should look like shown below, which relies on built-in type conversion from Uri to ImageSource:
<Grid>
<Image Width="10" Source="{Binding Path=ImageUri}" />
</Grid>
Declare the Properties.Resources.LedGreen property as ImageSource and set it to Uri location rather than the Bitmap object.
Or if you insist of storing it as a bitmap you can get the source by returning Properties.Resources.LedGreen.ImageSource which will be of type ImageSource.
I would prefer the first approach.
I cannot for the life of me figure out how to change a ToggleButton image when clicked. I have looked up countless examples and they are all outdated and no longer work. Or if they do I cannot get them to work. Does anyone have an up to date example I could look at or any suggestions?
I tried doing it in the code behind first. The example I found used a BitmapImage but this is not possible anymore as the BeginInit method cant be used due to security reasons.
Next I tried numerous style triggers but I get way to many compile errors even when they are directly copied and modified to fit the correct parameters. So I am stuck. I cant figure out how to use an EventTrigger to do it nor do any older examples seem to work. Anyone have any ideas?
Why not something like:
<ToggleButton x:Name="b">
<Image Src="myImage.png" Visibility="{Binding ElementName=b,Path=IsChecked,Converter="{StaticResource BooleanToVisibilityConverter}}"/>
<Image Src="myOtherImage.png" Visibility="{Binding ElementName=b,Path=IsChecked,Converter="{StaticResource BooleanToVisibilityConverter,ConverterParameter=Invert}}"/>
</ToggleButton>
Where you have a boolean to visibility converter that can accept a parameter to invert the bool.
Edit:
You'll need to define a converter so that it can convert the bool? from the IsChecked property to a Visibility enum. That's what all the binding code does. There is a basic implementation here that will convert to Visibility.Visible when true and Visibility.Collapsed when false. You need to add a check for the parameter so that it inverts the visibility when Invert is passed (to toggle between two images).
The other way to do this is to define images in the style and use the visual states for Checked and Unchecked to flip flop the images. You can apply a style to multiple buttons but it's hard to vary the images per-button (what my solution does).
This is how you set up a Resource
XAML
<!-- Place this in your window -->
xmlns:converters="clr-namespace:NameSpace"
<!-- Place this above your root UI -->
<Window.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
Then use the converter here BooleanToVisibilityConverter
you can use ImageToggleButton and ImageToggleButtonSideBySide (if you want a Mac-style toggle [or 2-state radio could call it] button) from ImageButtons project of ClipFlair project codebase
I have stackpanel in a canvas
The stackpanel has
<Canvas x:Name="MyCanvas">
<Slider Template="{StaticResource simpleSlider}" x:Name="seekBar" Thumb.DragStarted="seekBar_DragStarted" Thumb.DragCompleted="seekBar_DragCompleted" Canvas.Left="347" Canvas.Top="746" Width="900" Height="2" />
<Rectangle Height="5" />
<StackPanel Canvas.Left="200" Canvas.Right = "100">
</StackPanel>
</Canvas>
At runtime I need to change the location of the objects within the StackPanel.
Ie seekBar.Canvas.Left = 50
The "Canvas.Left" is an example of attached dependency property. The syntax for the C# is:
Canvas.SetLeft(myStackPanel, 50);
Where myStackPanel is any custom name you must assign using x.Name in the xaml.
You should use Canvas.SetLeft and Canvas.SetRight methods.
Caveat: I'm assuming that by this:
At runtime i need to change the location of the objects within the StackPanel.
You mean that you need to be able to set the Left position of the StackPanel itself (irrespective of what it contains). If this is not what you mean (for example, you don't have anything called seekBar in your example Xaml, even though you reference it in your code), please clarify.
The Canvas uses Attached Dependency Properties (as do other layout items, such as the Grid) to track layout information about contained items. Because of this, you'll either have to use the GetLeft and SetLeft functions on Canvas, GetValue and SetValue functions on your StackPanel to manipulate these values.
Do this, you'll need to give your StackPanel a name. I'll call it stack.
Given your example, you would do either this:
Canvas.SetLeft(stack, 50);
or this:
stack.SetValue(Canvas.LeftProperty, 50);
Note that the first version (SetLeft) is simply a wrapper around the second version, so use whichever you prefer.
You can get the value of any control by var x = btn.TransformToAncestor(this).Transform(new Point(0, 0));
where btn is the control which you want the margin of.
And then use yourstackpanel.SetValue(StackPanel.MarginProperty,new Thickness());