So I've been digging into the whole SuspendLayout()/ResumeLayout() logic for a while now and I've been trying to implement it in the most efficient manner. One question I'm unable to find an answer for is that of which I've asked in the title : Does the BringToFront() method go before or after you call ResumeLayout()? Does it matter? My initial thought process is no, it doesn't matter, because it's only changing the z-index of the control and not effecting the control's layout, but I just want to be sure.
Here's block of code from my project where my question comes into play:
Note:This project runs on a Motorola MC65 mobile device and uses .net compact 3.5 framework
/// <summary>
/// Initializes the <see cref="VerifyReplacementPanel"/> class
/// </summary>
/// <param name="hostControl">The panel this control is being added to</param>
/// <param name="original">The product being replaced</param>
/// <param name="replacement">The product replacing with</param>
/// <param name="logHelper">The log helper interface</param>
public VerifyReplacementPanel(Control hostControl, ProductModel original, ProductModel replacement, ILogHelper logHelper)
{
hostControl.SuspendLayout();
SuspendLayout();
HostControl = hostControl;
Product = original;
Replacement = replacement;
_logHelper = logHelper;
Size = Size.FullScreen();
// original product panel
var panOrig = new blkPan(472, 75) { Location = new Point(4, 147), BackColor = Color.White };
var originalProductPanel = new ProductPanelArrayModel(panOrig, _logHelper);
originalProductPanel.AddPanelWithPic(original);
Controls.Add(panOrig);
// replacement product panel
var panRepl = new blkPan(472, 75) { Location = new Point(4, panOrig.B + 100), BackColor = Color.White };
var replacementProductPanel = new ProductPanelArrayModel(panRepl, _logHelper);
replacementProductPanel.AddPanelWithPic(replacement);
Controls.Add(panRepl);
// no button
var btnNo = new PushButton("No", ObjectName, true) { Location = new Point(38, Bottom - 93 - 36) };
btnNo.Click += btnNo_Click;
Controls.Add(btnNo);
_btnNoTop = btnNo.Top;
// yes button
var btnYes = new PushButton("Yes", ObjectName, true) { Location = new Point(259, btnNo.Top) };
btnYes.Click += btnYes_Click;
Controls.Add(btnYes);
ResumeLayout(false);
HostControl.Controls.Add(this);
BringToFront();
HostControl.ResumeLayout();
}
My question is interested in this section :
ResumeLayout(false);
HostControl.Controls.Add(this);
BringToFront();
HostControl.ResumeLayout();
Also, am I even using it correctly? Thank you for your time.
Related
I am trying to reuse NumberBoxes for a GridView because having the NumberBoxes embedded directly in the GridView data template causes undesirable behavior, while reusing them does not. The problem is that I keep getting exceptions. They say "No installed components were detected" on the following line (templateRoot.FindName("NumberBox") as GridViewItem).Content = item.NumberBox; in this context
/// <summary>
/// The callback for updating a container in the GridView named CardGridView.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void UpdateGridViewContainer(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.Phase == 1)
{
Grid templateRoot = args.ItemContainer.ContentTemplateRoot as Grid;
CardItem item = args.Item as CardItem;
(templateRoot.FindName("NumberBox") as GridViewItem).Content = item.NumberBox;
TypedEventHandler<NumberBox, NumberBoxValueChangedEventArgs> handler =
(box, args) =>
{
if (!double.IsNaN(args.NewValue))
{
_viewModel.ChangeCount(args, item);
}
};
item.SetHandler(handler);
}
}
The exception is thrown when the Page that contains the GridView is left and renavigated to. I have tried nulling out the NumberBoxes when the page is left, but that did not work. Well, it appeared to before the issue cropped up again.
This is the code that nulls out the NumberBoxes
/// <summary>
/// Creates new NumberBoxes for when this Page is loaded again.
/// </summary>
private void ResetNumberBoxes()
{
foreach (CardItem card in CardGridView.Items.Cast<CardItem>())
{
card.ResetNumberBox();
}
CardGridView.ItemsSource = null;
CardGridView.Items.Clear();
}
ResetNumberBox is just setting the NumberBox to null and assigning a new one.
The exception details
System.Runtime.InteropServices.COMException
HResult=0x800F1000
Message=No installed components were detected. (0x800F1000)
Source=WinRT.Runtime
StackTrace:
at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|20_0(Int32 hr)
at ABI.Microsoft.UI.Xaml.Controls.IContentControlMethods.set_Content(IObjectReference _obj, Object value)
An update. I have removed the GridViewItem control from the DataTemplate and tried doing the following with the same result
CardItem item = args.Item as CardItem;
Grid.SetColumn(item.NumberBox, 1);
item.NumberBox.HorizontalAlignment = HorizontalAlignment.Center;
item.NumberBox.VerticalAlignment = VerticalAlignment.Center;
(templateRoot.FindName("GridViewTemplate") as Grid).Children.Add(item.NumberBox);
I also examined a heap dump right before the line that throws, and there was only one instance of the Grid, and the NumberBox had a parent of null.
I have a message extension for MS Teams (based on Bot Framework v3). When I create a ThumbnailCard and return it to user, Teams inserts name and logo of my app to card. Can I remove them somehow?
This is how I create a card
var card = new ThumbnailCard { Text = "some text", Title= "title"};
Here is a screenshot:
No, the attribution on cards created by a messaging extension can't be removed by the app. Teams will automatically show it.
The ThumbnailCard object has the constructor:
/// <summary>
/// Initializes a new instance of the ThumbnailCard class.
/// </summary>
/// <param name="title">Title of the card</param>
/// <param name="subtitle">Subtitle of the card</param>
/// <param name="text">Text for the card</param>
/// <param name="images">Array of images for the card</param>
/// <param name="buttons">Set of actions applicable to the current
/// card</param>
/// <param name="tap">This action will be activated when user taps on
/// the card itself</param>
public ThumbnailCard(string title = default(string), string subtitle = default(string), string text = default(string), IList<CardImage> images = default(IList<CardImage>), IList<CardAction> buttons = default(IList<CardAction>), CardAction tap = default(CardAction))
{
Title = title;
Subtitle = subtitle;
Text = text;
Images = images;
Buttons = buttons;
Tap = tap;
CustomInit();
}
Have you tried with images = new List<CardImage>() ? same thing for buttons
I'm currently facing a problem with printing a Plotmodel to an XPS-File.
What I have so far:
/// <summary>
/// Plotmodel to XPS-File
/// </summary>
/// <param name="model">The model</param>
/// <param name="fileName">The fileName</param>
/// <param name="width">Width of the model</param>
/// <param name="height">Height of the model</param>
public void Export(PlotModel model, string fileName, double width, double height)
{
try
{
using (Package xpsPackage = Package.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (var doc = new XpsDocument(xpsPackage))
{
var g = new Grid();
var p = new OxyPlot.Wpf.Plot { Model = model }; //Problem?
g.Children.Add(p);
var size = new Size(width, height);
g.Measure(size);
g.Arrange(new Rect(size));
g.UpdateLayout();
if (xpsdw == null) //XpsDocumentWriter xpsdw
xpsdw = XpsDocument.CreateXpsDocumentWriter(doc);
}
if (xpsdw != null)
{
xpsdw.Write(g);
}
}
}
}
This Code works fine (once), but the Problem is: No matter how often you use this method, you will always have just one Page with data. So if you want to print a second Plotmodel into the XPS-File the old one is deleted and you can only see the new one.
So the Question is:
Do you have an idea, how to append the new Plotmodel to the old XPS-File without overwriting it?
I also tried to use:
XpsExporter.Export(model, fileName, width, height);
instead of my function, but this didn't worked either.
If you know in advance that you will be writing multiple plots to a single file, you should look into VisualsToXpsDocument.
If you truly must append additional pages to an existing document on disk, it will be more difficult. You will need to dig down through the existing document to get to a FixedDocument (a child of the FixedDocumentSequence). Once you have the FixedDocument, you can add a new PageContent object to it. There is an example near the bottom of this thread.
I am trying to do the following to hide the title field from the new and edit form but its still visible.
pls help
/// <summary>
/// Adds source list and content type.
/// </summary>
/// <param name="currentWeb"></param>
private void AddSourcesList(SPWeb currentWeb)
{
currentWeb.AllowUnsafeUpdates = true;
#region Add Source content type.
if(currentWeb.ContentTypes[SponsoringCommon.Constants.CONTENTTYPES_SOURCES_NAME] == null)
{
#region Hides title column
currentWeb.Lists.Add(SponsoringCommon.Constants.LISTNAMES_SOURCES_NAME, string.Empty, SPListTemplateType.GenericList);
SPList sourceList = currentWeb.Lists.TryGetList(SponsoringCommon.Constants.LISTNAMES_SOURCES_NAME);
SPField titleField = sourceList.Fields.GetField("Title");
titleField.Required = false;
titleField.ShowInEditForm = false;
titleField.ShowInDisplayForm = false;
titleField.ShowInNewForm = false;
titleField.Hidden = true;
titleField.Update();
#endregion
I cannot see the rest of the code, but I had similar problem, and the thing I was missing is to .Update() the List and the Web. So in your case try to update sourceList and at the end currentWeb.
Hopefully, it will help solve your problem.
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.