Creating Scratch card effect on Windows Phone c# xaml - c#

I would like to create a scratch card effect on the Windows Phone. However my current solution seem sluggish and the scratch effect look weird(refer to the screenshot below). The experience is very poor as compared to those that i had seen on iOS.
Would appreciate if someone could guide me toward it. Below are my current code.
<Grid Width="Auto" Height="Auto" Background="Black">
<Viewbox Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid Height="60" Width="60" Background="White">
<InkPresenter x:Name="inkP" Width="60" Height="60">
<InkPresenter.Background>
<ImageBrush Stretch="Fill" ImageSource="/Assets/image.png"/>
</InkPresenter.Background>
<Grid Height="60" Width="60">
<TextBlock x:Name="lblsecretText" HorizontalAlignment="Center" TextWrapping="Wrap" Text="LOL" VerticalAlignment="Center" Width="60" Foreground="Black" TextAlignment="Center" FontSize="5.333"/>
</Grid>
</InkPresenter>
</Grid>
</Viewbox>
</Grid>
Stroke s;
int mycol = 0;
public MainPage()
{
InitializeComponent();
inkP.MouseMove += new MouseEventHandler(inkP_MouseMove);
for (int i = 0; i < 60; i++)
{
for (int l = 0; l < 60; l++)
{
Stroke bigStroke = new Stroke();
bigStroke.StylusPoints.Add(new StylusPoint(i, l));
inkP.Strokes.Add(bigStroke);
}
}
}
StylusPoint _lastPoint;
void inkP_MouseMove(object sender, MouseEventArgs e)
{
StylusPointCollection pointErasePoints = e.StylusDevice.GetStylusPoints(inkP);
pointErasePoints.Insert(0, new StylusPoint(e.GetPosition(inkP).X, e.GetPosition(inkP).Y));
//Compare collected stylus points with the ink presenter strokes and store the intersecting strokes.
StrokeCollection hitStrokes = inkP.Strokes.HitTest(pointErasePoints);
if (hitStrokes.Count > 0)
{
foreach (Stroke hitStroke in hitStrokes)
{
inkP.Strokes.Remove(hitStroke);
}
}
_lastPoint = pointErasePoints[pointErasePoints.Count - 1];
}

Your strokes are beeing removed point by point.
You can adjust this by changing your MainPage constructor to:
public MainPage()
{
InitializeComponent();
inkP.MouseMove += new MouseEventHandler(inkP_MouseMove);
for (int i = 0; i < 60; i++)
{
Stroke bigStroke = new Stroke();
for (int l = 0; l < 60; l++)
{
bigStroke.StylusPoints.Add(new StylusPoint(i, l));
}
inkP.Strokes.Add(bigStroke);
}
}
This will add the strokes line by line.
When you remove them, they will be removed line by line.

Related

WPF Custom Window Maximization Problems

I'm quite new to WPF and am trying to build a GUI in Blend, but I'm running into all sorts of issues.
I want my finished product to look like this: https://imgur.com/a/BU8Te
(the red is just a placeholder for icons).
Here is the XAML I've got so far:
<Window x:Class="GUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:GUI"
mc:Ignorable="d"
Title="GUI"
Height="840"
Width="920"
WindowStyle="none"
ResizeMode="CanResizeWithGrip"
AllowsTransparency="true"
MouseLeftButtonDown="Window_MouseLeftButtonDown"
WindowStartupLocation="CenterScreen"
Background="Transparent"
MaxWidth="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
MaxHeight="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}">
<Border x:Name="shadow">
<Grid x:Name="grid" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="100"/>
<RowDefinition Height="2"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="#F9F9F9" />
<Border Grid.Row="1" Background="#F9F9F9" />
<Border Grid.Row="2" Background="#E9E9E9" />
<DockPanel Grid.Row="0" LastChildFill="False">
<Button x:Name="btnClose"
DockPanel.Dock="Right"
VerticalAlignment="Center"
Height="20" Width="20"
Click="btnClose_Click"
Style="{DynamicResource CloseButton}">
<Path Data="m 357.0883 499.0572 12.62375 12.6275 5.31375 -5.31625 -12.62625 -12.62625 12.62625 -12.61875 -5.31375 -5.3125 -12.62375 12.62 -12.6325 -12.62 -5.30375 5.3125 12.6175 12.61875 -12.6175 12.62625 5.30375 5.31625 12.6325 -12.6275 z" Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="btnMaximise"
DockPanel.Dock="Right"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="20" Width="20"
Click="btnMaximise_Click"
Style="{DynamicResource TitleButton}">
<Path Data="M4.3685131,23.127279L4.3685131,47.283243 47.117023,47.283243 47.117023,23.127279z M0,10.684L53.755001,10.684 53.755001,51.668001 0,51.668001z M8.5679998,0L58.668022,0 64,0 64,5.6864691 64,45.317999 58.668022,45.317999 58.668022,5.6864691 8.5679998,5.6864691z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,0" ></Path>
</Button>
<Button x:Name="btnMinimise"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DockPanel.Dock="Right"
Height="20" Width="20"
Click="btnMinimise_Click"
VerticalContentAlignment="Bottom"
Style="{DynamicResource TitleButton}">
<Button.Content>
<Path Data="M0,20L53.333,20 53.333,8.888 0,8.888z"
Stretch="Uniform" Fill="#FFAAAAAA" Width="10" Margin="0,0,0,5"></Path>
</Button.Content>
</Button>
</DockPanel>
</Grid>
</Border>
</Window>
But when I maximise the window, the top left corner is off my screen (-15, -15 maybe?) and the bottom right corner is also too far up and left because of this. I modified some code that I found online (can't remember the source) which fixed this:
private bool isMaximized;
private Rect normalBounds;
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized && !isMaximized)
{
// max
WindowState = WindowState.Normal;
isMaximized = true;
normalBounds = RestoreBounds;
Height = SystemParameters.WorkArea.Height;
MaxHeight = Height;
MinHeight = Height;
Top = 0;
Left = 0;
Width = SystemParameters.WorkArea.Width;
SetMovable(false);
}
else if (WindowState == WindowState.Maximized && isMaximized)
{
// min
WindowState = WindowState.Normal;
isMaximized = false;
MaxHeight = Double.PositiveInfinity;
MinHeight = 0;
Top = normalBounds.Top;
Left = normalBounds.Left;
Width = normalBounds.Width;
Height = normalBounds.Height;
SetMovable(true);
}
}
private void SetMovable(bool enable)
{
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (enable)
source.RemoveHook(WndProc);
else
source.AddHook(WndProc);
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;
switch (msg)
{
case WM_SYSCOMMAND:
int command = wParam.ToInt32() & 0xfff0;
if (command == SC_MOVE)
handled = true;
break;
}
return IntPtr.Zero;
}
Now that works perfectly, but I'm really struggling to get this to work with a drop shadow on the window. When I add a 10px border to the window and set the dropshadow on this, I get the resizing icon in my border and not in my window:
https://imgur.com/a/S9oLK
I also had to modify the StateChanged event method to hide the border when maximised:
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized && !isMaximized)
{
// max
WindowState = WindowState.Normal;
isMaximized = true;
normalBounds = RestoreBounds;
Height = SystemParameters.WorkArea.Height;
MaxHeight = Height;
MinHeight = Height;
Top = 0;
Left = 0;
Width = SystemParameters.WorkArea.Width;
SetMovable(false);
this.grid.Margin = new Thickness(0);
this.BorderThickness = new Thickness(0);
}
else if (WindowState == WindowState.Maximized && isMaximized)
{
// min
WindowState = WindowState.Normal;
isMaximized = false;
MaxHeight = Double.PositiveInfinity;
MinHeight = 0;
Top = normalBounds.Top;
Left = normalBounds.Left;
Width = normalBounds.Width;
Height = normalBounds.Height;
SetMovable(true);
this.grid.Margin = new Thickness(10);
this.BorderThickness = new Thickness(10);
}
}
But this obviously doesn't work when the window is snapped to the edge of a screen: https://i.imgur.com/pGC1fio.png
To summarise, my issues are:
Resize grabber is in border not main window.
I don't know how to hide the border when the window is snapped to the edge of the screen.
Is there a simple way to fix this? I feel like I'm having to create a very hacky fix for all of this and thought it would be a lot easier to implement a custom window like this.
Thanks in advance for any help.

ListView Scrolling does not work when Manipulation events wired into ListviewItem - WP8.1

I have wired Manipulation events with the listviewitem to capture left swipe and right swipe. But when I try to scroll down the listview, it does not work! The manipulation events get fired and the listview does not scroll!
This is the listview Datatemplate
<Grid Height="60" Width="380" Margin="0,0,0,1">
<Grid x:Name="ItemGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Width="380" Height="60" Background="Orange" Canvas.ZIndex="2"
ManipulationMode="TranslateX" ManipulationStarted="On_ChannelItem_ManipulationStarted" ManipulationDelta="On_ChannelItem_ManipulationDelta" ManipulationCompleted="OnChannelItemManipulationCompleted">
<TextBlock x:Name="titleTextBlock" Margin="20,0,0,0" Canvas.ZIndex="2" VerticalAlignment="Center" TextAlignment="Left" FontSize="25" >
</TextBlock>
</Grid>
<Grid x:Name="DelGrid" Opacity="0.0" HorizontalAlignment="Right" VerticalAlignment="Center" Height="60" Background="Red" Canvas.ZIndex="-1" Tapped="On_ChannelDelete_Tap" Width="380">
<Button Content="X" FontSize="25" Canvas.ZIndex="-1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="380" BorderThickness="0" />
</Grid>
</Grid>
This is the manipulation events
private void OnChannelItemManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
Grid ChannelGrid = (Grid)sender;
Grid DeleteGrid = (Grid)((Grid)(ChannelGrid.Parent)).Children[1];
double dist = e.Cumulative.Translation.X;
if (dist < -100) // Swipe left
{
Storyboard SwipeLeft = new Storyboard();
DoubleAnimation OpacityAnimation = new DoubleAnimation();
OpacityAnimation.EnableDependentAnimation = true;
OpacityAnimation.From = 0.0;
OpacityAnimation.To = 1.0;
OpacityAnimation.BeginTime = TimeSpan.FromMilliseconds(0);
OpacityAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(1));
Storyboard.SetTarget(OpacityAnimation, DeleteGrid);
Storyboard.SetTargetProperty(OpacityAnimation, "Opacity");
SwipeLeft.Children.Add(OpacityAnimation);
DoubleAnimation WidthAnimation = new DoubleAnimation();
WidthAnimation.EnableDependentAnimation = true;
WidthAnimation.From = 380;
WidthAnimation.To = 0;
WidthAnimation.BeginTime = TimeSpan.FromMilliseconds(30);
WidthAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(WidthAnimation, ChannelGrid);
Storyboard.SetTargetProperty(WidthAnimation, "Width");
SwipeLeft.Children.Add(WidthAnimation);
SwipeLeft.Begin();
}
else if (dist > 100) // Swipe right
{
Storyboard SwipeRight = new Storyboard();
ColorAnimation changeColorAnimation = new ColorAnimation();
changeColorAnimation.EnableDependentAnimation = true;
changeColorAnimation.To = Colors.Green;
changeColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(100));
Storyboard.SetTarget(changeColorAnimation, ChannelGrid);
PropertyPath p = new PropertyPath("(ChannelGrid.Background).(SolidColorBrush.Color)");
Storyboard.SetTargetProperty(changeColorAnimation, p.Path);
SwipeRight.Children.Add(changeColorAnimation);
SwipeRight.Begin();
}
}
How do I enable the normal listview scrolling as well as the swipe? Vertical Scrolling is possible when I remove the manipulation events
Update your manipulation mode to include System:
ManipulationMode="TranslateX,System"

Creating a simple WPF map control from scratch

I really want to create my own map control in WPF because the only one that would be suitable for my requirements would be the Google Maps JavaScript API because it can do almost anything I need but that is only for web and mobile and I have tried the Bing and ESRI maps but they can't do what I want.
I have started a little experiment project to see if I can load the tiles when zooming and it kind of works, here is the code:
<ScrollViewer Margin="10" PanningMode="Both" HorizontalScrollBarVisibility="Visible">
<Canvas x:Name="lyrTiles" Height="3000" Width="3000"/>
</ScrollViewer>
<Grid x:Name="lyrControl" Margin="10">
<Button x:Name="moveUp" Content="U" HorizontalAlignment="Left" Margin="35,10,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Button x:Name="moveRight" Content="R" HorizontalAlignment="Left" Margin="55,30,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Button x:Name="moveDown" Content="D" HorizontalAlignment="Left" Margin="35,50,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Button x:Name="moveLeft" Content="L" HorizontalAlignment="Left" Margin="15,30,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Button x:Name="zoomIn" Content="ZI" HorizontalAlignment="Left" Margin="35,81,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Button x:Name="zoomOut" Content="ZO" HorizontalAlignment="Left" Margin="35,311,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
<Slider x:Name="zoomSlider" HorizontalAlignment="Left" Margin="35,106,0,0" VerticalAlignment="Top" Orientation="Vertical" Height="200" Width="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Interval="1"/>
<Button x:Name="typeHybrid" Content="Hybrid" HorizontalAlignment="Right" Margin="0,10,65,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
<Button x:Name="typeTerrain" Content="Terrain" HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
<Button x:Name="typeSatellite" Content="Satellite" HorizontalAlignment="Right" Margin="0,10,120,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
<Button x:Name="typeRoad" Content="Road" HorizontalAlignment="Right" Margin="0,10,175,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
<Label x:Name="copyright" Content="Map data ©2014 Google" HorizontalAlignment="Right" VerticalAlignment="Bottom" Padding="0" Width="200" FontSize="10" FontFamily="Calibri" FontWeight="Bold"/>
</Grid>
<Canvas x:Name="lyrActive" Margin="10,10,27,28" MouseWheel="lyrActive_MouseWheel" Background="#00000000"/>
public int zoomLevel = 0;
public int zoomWidth = 2;
public MainWindow()
{
InitializeComponent();
Image i = new Image(); i.Width = 250; i.Height = 250; i.Margin = new Thickness(0, 0, 0, 0);
i.Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/0/0/0.png"));
lyrTiles.Children.Add(i);
}
private void lyrActive_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
lyrTiles.Children.Clear();
zoomLevel += 1; zoomWidth = zoomWidth + zoomWidth / 2;
for (int x = 0; x < zoomWidth; x++)
{
for (int y = 0; y < zoomWidth; y++)
{
lyrTiles.Children.Add(new Image()
{
Margin = new Thickness(250 * x, 250 * y, 0, 0),
Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/" + zoomLevel + "/" + x + "/" + y + ".png"))
});
}
}
}
}
private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > 0)
{
lyrTiles.Children.Clear();
zoomLevel += 1; zoomWidth = zoomWidth + zoomWidth / 2;
for (int x = 0; x < zoomWidth; x++)
{
for (int y = 0; y < zoomWidth; y++)
{
lyrTiles.Children.Add(new Image()
{
Margin = new Thickness(250 * x, 250 * y, 0, 0),
Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/" + zoomLevel + "/" + x + "/" + y + ".png"))
});
}
}
}
}
Is this the correct way I should be rendering the tiles? I know I have to remove ones that are not visible but this is just a very very simple project to see what I can actually do to make a map. How can I start to make this work better?
Also, I think that the biggest and most important thing will be the coordinates because they are used from everything from locating the centre of the map so it can download the correct tiles to placing markers at specific locations. How can I do this, do I need some sort of huge latitude and longitude axis?
Here's a number of projects that might save you some work:
OpenSource:
http://www.codeproject.com/Articles/238551/WPF-Map-App-WPF-meets-Google-Geocoding-Static-Maps
http://xamlmapcontrol.codeplex.com/
http://greatmaps.codeplex.com/
http://wpfsharpmapcontrols.codeplex.com/
Commercial:
http://thinkgeo.com/map-suite-developer-gis/wpf-edition/
http://resources.arcgis.com/en/help/runtime-wpf/concepts/index.html#//017000000031000000
https://www.carmenta.com/en/products/carmenta-engine/overview
http://www.componentsource.com/products/componentart-maps-for-wpf/index-gbp.html
If you don't mind using Bing:
http://msdn.microsoft.com/en-us/library/hh750210.aspx
http://visualstudiomagazine.com/Articles/2012/04/01/Map-Your-Apps.aspx?Page=1

convert this UniformGrid xaml language to C#

Hi everyone i want to convert this xaml code to c# code
please help me using a looping to save memory or line
please help me
<UniformGrid Width="500" Height="500" x:Name="ChessBoard" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid x:Name="Grid1" Background="Yellow" />
<Grid x:Name="Grid2" Background="Black" />
<Grid x:Name="Grid3" Background="Yellow" />
<Grid x:Name="Grid4" Background="Black" />
<Grid x:Name="Grid5" Background="Yellow" />
<Grid x:Name="Grid6" Background="Black" />
<Grid x:Name="Grid7" Background="Yellow" />
<Grid x:Name="Grid8" Background="Black" />
<Grid x:Name="Grid9" Background="Yellow" />
</UniformGrid>
please
UniformGrid ChessBoard = new UniformGrid();
ChessBoard.Width = 500;
ChessBoard.Height = 500;
ChessBoard.HorizontalAlignment = HorizontalAlignment.Center;
ChessBoard.VerticalAlignment = VerticalAlignment.Center;
Grid chressBox = new Grid();
SolidColorBrush yell = new SolidColorBrush(Colors.Yellow);
SolidColorBrush blk = new SolidColorBrush(Colors.Black);
for (int ii = 1; ii <= 9; ii++)
{
if (ii % 2 == 0)
{
chressBox.Background = blk;
chressBox.Name = "Grid" + ii.ToString();
ChessBoard.Children.Add(chressBox);
}
else
{
chressBox.Background = yell;
chressBox.Name = "Grid" + ii.ToString();
ChessBoard.Children.Add(chressBox);
}
}
LayoutRoot.Children.Add(ChessBoard);
itry to create that, but still wrong
For a full chessboard you could do something like this
Brush defaultBrush = new SolidColorBrush(Colors.Yellow);
Brush alternateBrush = new SolidColorBrush(Colors.Black);
for (int x = 0; x < 8; ++x)
{
for (int y = 0; y < 8; ++y)
{
Grid cell = new Grid();
cell.Background = (y+x) % 2 == 0 ? defaultBrush : alternateBrush;
ChessBoard.Children.Add(cell);
}
}
Here is a version with only a single for loop
Brush defaultBrush = new SolidColorBrush(Colors.Yellow);
Brush alternateBrush = new SolidColorBrush(Colors.Black);
for (int i = 0; i < 64; ++i)
{
Grid cell = new Grid();
cell.Background = (i + i / 8) % 2 == 0 ? defaultBrush : alternateBrush;
ChessBoard.Children.Add(cell);
}
This code assumes you have a ChessBoard defined as a UniformGrid as in your example.

backgroundworker+wpf -> frozen window

-progressbar always 0%
-the window is froozen (while DoWork r.)
-if System.threading.thread.sleep(1) on - works perfectly
whats the problem?
private void btnNext_Click(object sender, RoutedEventArgs e)
{
this._worker = new BackgroundWorker();
this._worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
long current = 1;
long max = generalMaxSzam();
for (int i = 1; i <= 30; i++)
{
for (int j = i+1; j <= 30; j++)
{
for (int c = j+1; c <= 30; c++)
{
for (int h = c+1; h <= 30; h++)
{
for (int d = h+1; d <= 30; d++)
{
int percent = Convert.ToInt32(((decimal)current / (decimal)max) * 100);
this._worker.ReportProgress(percent);
current++;
//System.Threading.Thread.Sleep(1); - it works well
}
}
}
}
}
};
this._worker.WorkerReportsProgress = true;
this._worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
this.Close();
};
this._worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
{
this.statusPG.Value = args.ProgressPercentage;
};
this._worker.RunWorkerAsync();
}
<Window x:Class="SzerencsejatekProgram.Create"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Létrehozás" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="500" Width="700">
<DockPanel>
<Button DockPanel.Dock="Right" Name="btnNext" Width="80" Click="btnNext_Click">Tovább</Button>
<StatusBar DockPanel.Dock="Bottom">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="1">
<TextBlock Name="statusText"></TextBlock>
</StatusBarItem>
<StatusBarItem Grid.Column="2">
<ProgressBar Name="statusPG" Width="80" Height="18" IsEnabled="False" />
</StatusBarItem>
<StatusBarItem Grid.Column="3">
<Button Name="statusB" IsCancel="True" IsEnabled="False">Cancel</Button>
</StatusBarItem>
</StatusBar>
</DockPanel>
</Window>
Your code runs a very tight loop and at its center it calls ReportProgress().
This means that your MessageQueue is swamped with requests to execute the Progress updates.
If you build some delay (Thread.Sleep(100)) into the Bgw thread you will see the responsiveness improve.
A more practical solution is to move the reporting out to the outer loop. In your case:
for (int i = 1; i <= 30; i++)
{
int percent = (i * 100) / 30;
_worker.ReportProgress(percent);
for(int j = 0; ....)
....
}
If you only have 1 loop, build in a delay: 'if ((counter % 100) == 0) ...`
Your target here is the user, aim for between 10 and 100 calls to Reportprogress.
Your anonymous method for the ProgressChanged event will run on UI thread. since you're reporting frequent progress it will be queued up in by the dispatcher and blocks the UI.
if (current++ % onePercent == 0)
{
int percent = Convert.ToInt32(((decimal)current / (decimal)max) * 100);
this._worker.ReportProgress(percent, new WorkerUserState { current = current, max = max });
}
this works well.

Categories