|
Strange, I see Length and Capacity exposed here:
Reference Source[^]
and they are on the interface, so short of throwing NotSupportedException or similar they should not be able to stop you.
The finalizer not being called is expected - not as in "it should not be called", but as in "if it had been called the original code you had would not leak"
I have no idea why your stream stops the image freezing. There might have some "magic" detecting if it is an instance of MemoryStream - for example kicking it into synchronous initialization, but that is not something I have looked into for many years.
|
|
|
|
|
I have eventually found a "solution" to this problem.
Be prepared: that empirical solution makes no real sense, but this works...
Solution was to go through the following convertions:
- byte[] to Bitmap using GetConverter;
- Bitmap redrawn to a new Bitmap using GDI+ Graphics
- Bitmap to byte[] again using ImageConverter
- byte[] to ImageSource using the previously mentioned BitmapFromRaw Method.
Any attempt to simplify this code lead to the memory leak to come back.
No clue how this could be the way to get the GC do its job. Like in relativity, the shortest path is not always the straight one...
Here is the the extra code that works for me. It makes my eyes bleed and I'm not proud of it. So again, if anyone could get something cleaner working, please propose.
public static ImageSource? BitmapFromRawNoLeak(byte[]? imageData)
{
if (imageData == null) return null;
ImageSource? image = null;
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
using (Bitmap? bmp = (Bitmap?)tc.ConvertFrom(imageData))
{
if (bmp == null) return null;
bmp.SetResolution(96, 96);
using (Bitmap source = new Bitmap(bmp.Width, bmp.Height))
{
if (source == null) return null;
using (Graphics g = Graphics.FromImage(source))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);
}
ImageConverter converter = new ImageConverter();
var vect = (byte[])converter.ConvertTo(source, typeof(byte[]));
image = BitmapFromRaw(vect);
image?.Freeze();
}
}
return image;
}
|
|
|
|
|
I use WriteableBitmap (the UWP version) without any issues.
Maybe it can help you (the other version).
WriteableBitmap Class (System.Windows.Media.Imaging) | Microsoft Docs
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Thanks Gerry.
I've tried to apply your tip, but to be honest, I couldn't find the way to make this WriteableImage from a byte[] array. This byte[] doesn't contain raster bitmap, but a jpeg-formatted data.
|
|
|
|
|
Starwer wrote:
using (Bitmap source = new Bitmap(bmp.Width, bmp.Height))
{
if (source == null) return null; The result of new Bitmap(...) can never be null . If the constructor fails for some reason, you will get an exception, not a null object.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
HI yall,
I am using MahApp library for nice Office like top level windows.
For that one has to add MahApp resource dictionary in the App.xaml dictionary.
Also, to be fair, in a bout of excessibve enthusiasm I started reference MahApp brushed and color in a some of my control as well.
Now, I dont really like MahApp style on some control I havent used so far, like GroupBox and, yuk, TabControl.
Is there an easy way I can restore the original TabControl style, while also keeping the MapApp resource dictionaries in my App.xaml merge ditionaries?
|
|
|
|
|
|
I got a custom image loading markup extension, which I use like so:
<Image Source="{gxv:ImageResource Resources/Images/expand.svg}" Height="16" Width="16" />
And this works fine.
However, when viewing or editing the Xaml in Visual Studio I got designer warnings, like so:
Error XDG0062 Cannot locate resource 'resources/images/expand.svg'. D:\MyGIT\brpworld\RPGStoryboards.Extensions\Map\ImagePicker.xaml 105
How could I get rid of those warnings?
Or, even better, could I load those picture at design time?
|
|
|
|
|
I have a TextBox bound to a decimal. I'm using Clifford Nelson's [^] Number Only Behaviour for WPF.
I added a DP to toggle allowing decimals called AllowDecimals, but I've found a problem, andit's NOT with Clifford's code. And it only happens when BOUND to a property.
First, here's the OnTextInput
private static void OnTextInput(object sender, TextCompositionEventArgs e)
{
bool allowDecimals = GetAllowDecimals((Control)sender);
if (allowDecimals && e.Text.Any(c => c.Equals('.')))
{
}
else
{
if (e.Text.Any(c => !char.IsDigit(c)))
{
e.Handled = true;
}
}
}
As you can see by the comment, if I turn on AllowDecimals and type a '.', the code hits where it should, but I don't see it in the TextBox.
If I type some digits THEN arrow over in between two digits and type a '.', then it's accepted.
I beleive the problem is that the binding is trying to parse the value and somehow discards or swallows the decimal point.
The WPF ToolKit has a DecimalUpDown control. I don't really want to bring in that entire library just so I can enter a decimal point.
Anyone have a workaround or fix for this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I assume there is a reason why you are not using the numericupdown control and removing the U/D arrows. I would think changing the style from decimal to integer should be possible.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
I already stated why
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
WPFToolkit is like 1.5Mb
I too try to trim my application of dead weight...
It matters not much for business application, but end user application do benefit from small download files, I reckon...
|
|
|
|
|
Super Lloyd wrote: business application Yeah this is where I lived
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
As end users we download several Gb for Warcraft. 1.5 Mb was noticable in the dial up era; but these days your average webpage pulls in more.
Also, you're using a dot as a decimal-separator. The system may be set to use a comma.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
Eddy Vluggen wrote: Also, you're using a dot as a decimal-separator. The system may be set to use a comma.
Did you reply to the wrong person?!
|
|
|
|
|
Whehe, I did.
..but I'm not gonna rectify either
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
|
I have a UserControl with a data grid that I'm creating in code in a View Model. It looks like this [^]. I'm trying to set the Cell Style to show 2 decimal from the VM but you can see it's not working.
The first column is a string, and the remainder are Decimal.
Here's my Cell Style
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="Width" Value="75"/>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
<Setter Property="TextBlock.Text" Value="{Binding StringFormat={}{0:0.##}}"/>
<Setter Property="IsEnabled" Value="{Binding DataContext.AreFieldsEnabled, ElementName=budgetControl}"/>
</Style>
Here's how I'm creating the table in the VM and setting the Style. The Style is set in the foreach loop towards the bottom.
private void LoadTable()
{
if (Budgets.Count > 0)
{
BudgetTable = null;
BudgetTable = new DataTable();
DataColumn column = new DataColumn();
column.ColumnName = "Type";
column.DataType = System.Type.GetType("System.String");
column.ReadOnly = false;
BudgetTable.Columns.Add(column);
List<string> planElevations = new List<string>();
switch (BudgetType)
{
case BudgetType.Job:
var sheets = JobSequenceSheets.Where(x => x.Status == "New").ToList();
planElevations = sheets.Select(x => $"{x.Plan}{x.Elevation}").ToList();
break;
case BudgetType.Project:
planElevations = ProjectPlanTypeSummaries.Select(x => $"{x.Plan}{x.Elevation}").ToList();
break;
default:
throw new ArgumentException("Unhandled CASE statement");
break;
}
foreach (var planElevation in planElevations)
{
column = new DataColumn();
column.ColumnName = planElevation;
column.Caption = planElevation;
column.DataType = System.Type.GetType("System.Decimal");
column.ReadOnly = false;
BudgetTable.Columns.Add(column);
}
DataGridColumns = new ObservableCollection<DataGridColumn>();
string[] columnNames = (from dc in BudgetTable.Columns.Cast<DataColumn>()
select dc.ColumnName).ToArray();
foreach (string item in columnNames)
{
Binding binding = new Binding(item);
string styleName = "";
if (item == "Type")
{
binding.Mode = BindingMode.OneTime;
styleName = "budgetGridCellStyle";
}
else
{
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
styleName = "dataGridCurrencyCellStyle";
}
var style = Application.Current.FindResource(styleName) as Style;
var col = new DataGridTextColumn()
{
Header = item,
Binding = binding,
Visibility = Visibility.Visible,
CellStyle = style
};
DataGridColumns.Add(col);
}
foreach (var budget in Budgets)
{
AddRow(budget);
}
}
}
DataGrid XAML
<DataGrid Grid.Row="1"
x:Name="budgetGrid"
Style="{StaticResource dataGridStyle}"
GridLinesVisibility="All"
ItemsSource="{Binding BudgetTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Behaviors>
<cls:ColumnsBindingBehaviour Columns="{Binding DataContext.DataGridColumns,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource AncestorType=DataGrid}}" />
</i:Interaction.Behaviors>
<behaviours:Interaction.Triggers>
<behaviours:EventTrigger EventName="CellEditEnding">
<behaviours:InvokeCommandAction Command="{Binding ElementName=budgetControl, Path=DataContext.CellEditedCommand}"
PassEventArgsToCommand="True"/>
</behaviours:EventTrigger>
</behaviours:Interaction.Triggers>
</DataGrid>
What's the right way to do this?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
If the way you're doing it works without side-effects, that's the right way to do it.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
I have a... an unusual control (its a container for visuals), to which I just added a TextBox (user can click somewhere and add some text).
This control also listen to Key down event and on 1,2,3,4 it does something.
Now the problem is, it also happens when the user is typing in the TextBox, which is less than ideal, to say the least.
I can see that the KeyEventArgs.OriginalSource is different from KeyEventArgs.Source (my container), could I use that reliably perhaps? Any other tips?
|
|
|
|
|
In your TextBox.TextChanged event handler, before exiting the handler method, set e.Handled to true , and see if that works.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Interesting...
I gave it a go, and unfortunately the KeyDown happens before the TextInput event...
I tried to override OnKeyDown in the TextBox , and even though I called base.OnKeyDown first, setting Handled = true prevented text input entirely...
No matter, my test of only handling key input in global container if it was the original source worked!
Thanks for interesting suggestion though!
|
|
|
|
|
My next suggestion was to look at one of the preview events, and to make sure the source of the input was correct.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
BTW the inline text editor is progressing nicely.. now I "just" need to add the text to the map...
Text-Input — ImgBB
|
|
|
|
|
I have a FrameworkElement (subclass) in my app which is a host for custom Visual s (my app is a sort of drawing program).
Now I just put the first UIElement in the visual container. A UserControl which host a bunch of Control s, including a TextBox .
Now when the Text change and the text box resize and go outside the containing UserControl , it is clipped and does not show anymore.
I tried to set Clip to false on the UserControl , didn't help (in fact it was already false ).
Now in my UIElement I can be aware of the need to resize, thanks to
protected virtual void OnChildDesiredSizeChanged(UIElement child);
But I need to know that in my visual container.
At the moment it looks like it should only really be able to host & resize UIElement which implement some sort of INotifyResize interface, which I could inform thanks to this OnChildDesiredSizeChanged() method.
I wonder if there is already a way I can know that, with just any UIElement , not just the one made specifically to be hosted by that container.
EDIT / REMARK
5 minutes later... I think I might had answered my own question!
I could just override OnChildDesiredSizeChanged() in the visual container....
I think there might be some issues, because some ContainerVisual are involved in the Visual hierarchy... let's see...
EDIT2
So I tried that and it is really strange
protected override void OnChildDesiredSizeChanged(UIElement child)
{
base.OnChildDesiredSizeChanged(child);
child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
child.Arrange(new Rect(BoundedVisual.GetLocation(child), child.DesiredSize));
}
This method is called only once and the child didn't resize...
EDIT3
Ha, I see, this didn't work, it this was another child (the one which display the scollbar). got nothing for the text...
EDIT / FOUND a solution
I am using this UIElement event to do my reArrange() , it seems to be working
public event EventHandler LayoutUpdated;
modified 18-Dec-21 7:49am.
|
|
|
|
|