WPF UserControl background Transparency doesn't work - wpf

I try to pop up a usercontrol using own class ModalDialogManager : Control but the background doesn't seem transparent as shown on http://prntscr.com/6cgyc2
in my ModalDialogManager class, I did specify the windows to allow transparency:
Window w = new Window();
m_window = w;
w.Closing += w_Closing;
w.Owner = GetParentWindow(this);
w.DataContext = this.DataContext;
w.SetBinding(Window.ContentProperty, "");
w.Title = Title;
w.Icon = Icon;
w.Height = DialogHeight;
w.Width = DialogWidth;
w.ResizeMode = DialogResizeMode;
// SHOULD IT WORK?!
w.AllowsTransparency = true;
double t = GetParentWindow(this).Left;
if (IsBorderless)
{
w.WindowStyle = WindowStyle.None;
w.ShowInTaskbar = false;
if (IsStartUpLocationCenter)
{
w.WindowStartupLocation = WindowStartupLocation.CenterScreen;
}
else
{
w.Left = LeftPosition;
w.Top = RightPosition;
w.WindowStartupLocation = WindowStartupLocation.Manual;
}
}
else
{
w.WindowStartupLocation = WindowStartupLocation.CenterOwner;
}
if (IsModal)
w.ShowDialog();
else
w.Show();
but the UserControl design shows ok: http://prntscr.com/6cgyz8
Thus, I tried to use a window to attach the usercontrol and do window.showDialog() with a usercontrol as below:
Window w = new Window();
SolidColorBrush b = new SolidColorBrush();
b.Color = .Colors.Transparent;
w.Background = b;
Grid g = new Grid();
g.Children.Add(new ucSelectCloth());
w.Content = g;
g.Background = b;
w.Height = 300;
w.Width = 600;
w.ShowDialog();
As you can see that http://prntscr.com/6cgzdk the window doesn't look Transparent too.
Any thought?

window remains opaque until you set Window.AllowsTransparency property to true. Once you set Window.AllowsTransparency to true you have to set WindowStyle to None.
add following lines to your code,
w.WindowStyle = System.Windows.WindowStyle.None;
w.AllowsTransparency = true;

Related

Resizing of an AutoScroll Panel affects scrolled position

When I resize the following form with the right resize handle, the contained TableLayoutPanel gets decorated with scroll bars (as intended, panel1.AutoScroll = true) for smaller form sizes, but the TableLayoutPanel also gets displaced from its original position. See images below: after resizing the form with right resize handle only, the second one has its scroll bars not leftmost and the left border of the content is cut off.
It seems somehow that this behavior is tied to the existence of the nested RadioButtons because if I remove them (or replace them by another TextBox for example), the "normal" behavior is restored (TableLayoutPanel stays in place during resize).
What properties do I have to set in order to keep the content always stationary relative to the (top)left borders?
BTW: When I replace the panel1 by a TabControl + one TabPage, the "normal" behavior is also restored.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test
{
/// <summary>
/// Description of Form3.
/// </summary>
public partial class Form3 : Form
{
const int textBoxNameWidth = 500;
TableLayoutPanel testControl1;
Panel panel1;
TextBox textBoxName;
RadioButton radioButtonNo;
RadioButton radioButtonYes;
TableLayoutPanel tableLayoutPanelDecision;
public Form3()
{
testControl1 = new TableLayoutPanel();
panel1 = new Panel();
textBoxName = new TextBox();
radioButtonNo = new RadioButton();
radioButtonYes = new RadioButton();
tableLayoutPanelDecision = new TableLayoutPanel();
testControl1.AutoSize = true;
testControl1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
testControl1.Location = new Point(0, 0);
testControl1.Dock = DockStyle.None;
testControl1.ColumnCount = 2;
testControl1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
testControl1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
testControl1.RowCount = 2;
testControl1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
testControl1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
testControl1.Controls.Add(textBoxName, 1, 0);
testControl1.Controls.Add(tableLayoutPanelDecision, 1, 1);
textBoxName.Text = "New Boolean";
textBoxName.TextAlign = HorizontalAlignment.Center;
textBoxName.Anchor = (AnchorStyles.Left | AnchorStyles.Right);
textBoxName.TabStop = false;
textBoxName.Width = textBoxNameWidth;
tableLayoutPanelDecision.AutoSize = true;
tableLayoutPanelDecision.ColumnCount = 2;
tableLayoutPanelDecision.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
tableLayoutPanelDecision.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
tableLayoutPanelDecision.RowCount = 1;
tableLayoutPanelDecision.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tableLayoutPanelDecision.Controls.Add(radioButtonYes, 0, 0);
tableLayoutPanelDecision.Controls.Add(radioButtonNo, 1, 0);
tableLayoutPanelDecision.Dock = DockStyle.Fill;
radioButtonNo.Checked = true;
radioButtonNo.AutoSize = true;
radioButtonNo.TabIndex = 1;
radioButtonNo.TabStop = true;
radioButtonNo.Text = "False";
radioButtonNo.UseVisualStyleBackColor = true;
radioButtonNo.Anchor = AnchorStyles.None;
radioButtonYes.AutoSize = true;
radioButtonYes.TabIndex = 0;
radioButtonYes.Text = "True";
radioButtonYes.UseVisualStyleBackColor = true;
radioButtonYes.Anchor = AnchorStyles.None;
panel1.AutoScroll = true;
panel1.Controls.Add(testControl1);
panel1.Dock = System.Windows.Forms.DockStyle.Fill;
panel1.Location = new System.Drawing.Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new System.Drawing.Size(560, 219);
panel1.TabIndex = 1;
AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(560, 219);
Controls.Add(panel1);
Name = "Form3";
Text = "Form3";
}
}
}
The panel is trying to keep focusable controls within view for the user. To change that, you would have to use your own panel:
public class PanelEx : Panel {
protected override Point ScrollToControl(Control activeControl) {
return this.DisplayRectangle.Location;
}
}

WPF - pass data from page A to page B

So I want to pass data when I clicked an Canvas. So I have this code;
Canvas event_canvas = new Canvas();
event_canvas.Background = new SolidColorBrush(Color.FromRgb(66, 70, 77));
event_canvas.Width = 250;
event_canvas.Height = 60;
event_canvas.Margin = new Thickness(40, 0, 0, 0);
event_canvas.HorizontalAlignment = HorizontalAlignment.Left;
event_canvas.VerticalAlignment = VerticalAlignment.Top;
event_canvas.Cursor = Cursors.Hand;
#endregion
#region Grid (event_grid)
Grid event_grid = new Grid();
event_grid.Width = 250;
event_grid.Height = 60;
#endregion
#region TextBlock (event_text)
TextBlock event_text = new TextBlock();
event_text.VerticalAlignment = VerticalAlignment.Center;
event_text.HorizontalAlignment = HorizontalAlignment.Center;
event_text.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255));
event_text.Text = e.name;
#endregion
event_grid.Children.Add(event_text); // Add the textblock to the grid
event_canvas.Children.Add(event_grid); // Add the grid to the canvas
grid_events.Children.Add(event_canvas); // Add the canvas to the main grid.
// Click event registration
event_canvas.MouseLeftButtonDown += Event_canvas_MouseLeftButtonDown;
And then in the trigger;
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Page pg = new EventDetailPage();
// Replaces all the content!!!!!
this.Content = pg;
//throw new NotImplementedException();
}
I tried to add this;
var param = ((TextBlock)sender).Text;
Page pg = new EventDetailPage(param);
But that code doesn't work, it throws an error that I can't get a value.
How can I fix this issue?
Cast the sender argument to Canvas and then access the Grid through the Canvas' Children collecton and the TextBlock through the Grid's Children collecton:
private void Event_canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Canvas canvas = (Canvas)sender;
Grid event_grid = canvas.Children[0] as Grid;
TextBlock event_text = event_grid.Children[0] as TextBlock;
string text = event_text.Text;
...
}

GridSplitter Not present

I use this in code behind to test how to add a grid splitter programmatically. (I know, don't use code behind - But this is one of those rare cases I need to. (I think))
public partial class ContainerView : Window, IContainerView
{
[ImportingConstructor]
public ContainerView()
{
InitializeComponent();
SetUp();
}
public void SetUp()
{
_grid = new Grid();
//Single column/single row
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.ColumnDefinitions.Add(new ColumnDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
var button1 = new Button();
button1.Content = "Btn 1";
button1.Margin = new Thickness(5);
Grid.SetRow(button1, 0);
Grid.SetColumn(button1, 0);
var button2 = new Button();
button2.Content = "Btn 2";
button2.Margin = new Thickness(5);
Grid.SetRow(button2, 1);
Grid.SetColumn(button2, 2);
_grid.Children.Add(button1);
_grid.Children.Add(button2);
var splitterV = new GridSplitter();
Grid.SetRowSpan(splitterV, _grid.RowDefinitions.Count);
splitterV.VerticalAlignment = VerticalAlignment.Stretch;
splitterV.HorizontalAlignment = HorizontalAlignment.Right;
splitterV.ShowsPreview = true;
splitterV.Background = Brushes.Black;
Width = 5;
_grid.Children.Add(splitterV);
Grid.SetColumn(splitterV, 1);
Content = _grid;
}
I can see the two buttons, but the middle column is empty. The GridSplitter is not shown. What am I doing wrong?
You are absolutely correct but you are setting Window's width instead of GridSpitter's width & also you have to give it's ResizeBehaviour.
Instead of this :
Width = 5;
Set GridSpitter's Width & It's ResizeBehavior as :
splitterV.ResizeBehavior = GridResizeBehavior.PreviousAndNext;
splitterV.Width = 5;

Silverlight 4 WriteableBitmap ScaleTransform Exception but was working in v3

I am getting the following exception for code that used to work in silverlight 3 but has stopped working since upgrading to silverlight 4:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var OpenFileDialog = new OpenFileDialog();
OpenFileDialog.Filter = "*.jpg|*.jpg";
if (OpenFileDialog.ShowDialog() == true)
{
var file = OpenFileDialog.Files.ToArray()[0];
ScaleStreamAsBitmap(file.OpenRead(), 200);
}
}
public static WriteableBitmap ScaleStreamAsBitmap(Stream file, int maxEdgeLength)
{
file.Position = 0;
var src = new BitmapImage();
var uiElement = new System.Windows.Controls.Image();
WriteableBitmap b = null;
var t = new ScaleTransform();
src.SetSource(file);
uiElement.Source = src;
//force render
uiElement.Effect = new DropShadowEffect() { ShadowDepth = 0, BlurRadius = 0 }; ;
//calc scale
double scaleX = 1;
double scaleY = 1;
if (src.PixelWidth > maxEdgeLength)
scaleX = ((double)maxEdgeLength) / src.PixelWidth;
if (src.PixelHeight > maxEdgeLength)
scaleY = ((double)maxEdgeLength) / src.PixelHeight;
double scale = Math.Min(scaleX, scaleY);
t.ScaleX = scale;
t.ScaleY = scale;
b = new WriteableBitmap(uiElement, t);
return b;
}
}
}
Thanks
I had the same problem and I succeeded to resolve it!
b=new new WriteableBitmap(0, 0);
b.SetSource(file);
b.Render( new Image() { Source = src, Effect = new DropShadowEffect() { ShadowDepth = 0, BlurRadius = 0 } }, new ScaleTransform() { ScaleX = scaleX , ScaleY = scaleY });
And you can remove :uiElement and file.Position!

Using a Storyboard animation on a programmatically-added control

I'm trying to fade in a new control to my application's "app" area which is programmatically added after the existing controls are removed. My code looks like this:
void settingsButton_Clicked(object sender, EventArgs e)
{
ContentCanvas.Children.Clear();
// Fade in settings panel
NameScope.SetNameScope(this, new NameScope());
SettingsPane s = new SettingsPane();
s.Name = "settingsPane";
this.RegisterName(s.Name, s);
this.Resources.Add(s.Name, s);
Storyboard sb = new Storyboard();
DoubleAnimation settingsFade = new DoubleAnimation();
settingsFade.From = 0;
settingsFade.To = 1;
settingsFade.Duration = new Duration(TimeSpan.FromSeconds(0.33));
settingsFade.RepeatBehavior = new RepeatBehavior(1);
Storyboard.SetTargetName(settingsFade, s.Name);
Storyboard.SetTargetProperty(settingsFade, new PropertyPath(UserControl.OpacityProperty));
ContentCanvas.Children.Add(s);
sb.Children.Add(settingsFade);
sb.Begin();
}
However, when I run this code, I get the error "No applicable name scope exists to resolve the name 'settingsPane'."
What am I possibly doing wrong? I'm pretty sure I've registered everything properly :(
I wouldn't hassle with the NameScopes etc. and would rather use Storyboard.SetTarget instead.
var b = new Button() { Content = "abcd" };
stack.Children.Add(b);
var fade = new DoubleAnimation()
{
From = 0,
To = 1,
Duration = TimeSpan.FromSeconds(5),
};
Storyboard.SetTarget(fade, b);
Storyboard.SetTargetProperty(fade, new PropertyPath(Button.OpacityProperty));
var sb = new Storyboard();
sb.Children.Add(fade);
sb.Begin();
I solved the problem using this as parameter in the begin method, try:
sb.Begin(this);
Because the name is registered in the window.
I agree, the namescopes are probably the wrong thing to use for this scenario. Much simpler and easier to use SetTarget rather than SetTargetName.
In case it helps anyone else, here's what I used to highlight a particular cell in a table with a highlight that decays to nothing. It's a little like the StackOverflow highlight when you add a new answer.
TableCell cell = table.RowGroups[0].Rows[row].Cells[col];
// The cell contains just one paragraph; it is the first block
Paragraph p = (Paragraph)cell.Blocks.FirstBlock;
// Animate the paragraph: fade the background from Yellow to White,
// once, through a span of 6 seconds.
SolidColorBrush brush = new SolidColorBrush(Colors.Yellow);
p.Background = brush;
ColorAnimation ca1 = new ColorAnimation()
{
From = Colors.Yellow,
To = Colors.White,
Duration = new Duration(TimeSpan.FromSeconds(6.0)),
RepeatBehavior = new RepeatBehavior(1),
AutoReverse = false,
};
brush.BeginAnimation(SolidColorBrush.ColorProperty, ca1);
It is possible odd thing but my solution is to use both methods:
Storyboard.SetTargetName(DA, myObjectName);
Storyboard.SetTarget(DA, myRect);
sb.Begin(this);
In this case there is no error.
Have a look at the code where I have used it.
int n = 0;
bool isWorking;
Storyboard sb;
string myObjectName;
UIElement myElement;
int idx = 0;
void timer_Tick(object sender, EventArgs e)
{
if (isWorking == false)
{
isWorking = true;
try
{
myElement = stackObj.Children[idx];
var possibleIDX = idx + 1;
if (possibleIDX == stackObj.Children.Count)
idx = 0;
else
idx++;
var myRect = (Rectangle)myElement;
// Debug.WriteLine("TICK: " + myRect.Name);
var dur = TimeSpan.FromMilliseconds(2000);
var f = CreateVisibility(dur, myElement, false);
sb.Children.Add(f);
Duration d = TimeSpan.FromSeconds(2);
DoubleAnimation DA = new DoubleAnimation() { From = 1, To = 0, Duration = d };
sb.Children.Add(DA);
myObjectName = myRect.Name;
Storyboard.SetTargetName(DA, myObjectName);
Storyboard.SetTarget(DA, myRect);
Storyboard.SetTargetProperty(DA, new PropertyPath("Opacity"));
sb.Begin(this);
n++;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + " " + DateTime.Now.TimeOfDay);
}
isWorking = false;
}
}

Resources