Constructor | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar constructor

Windows 10 UWP Uygulamalarında InkCanvas ile imza almak

10 February 2016 2 yorum

Geçen hafta email ile aldığım bir soruyu cevaplamak üzere bu makaleyi yazıyorum.

Windows 10 UWP uygulamalarında eğer kullanıcının imzasını ekran üzerinde almak isterseniz InkCanvas sınıfını kullanabilirsiniz.

Hemen Visual Studio açıp yeni bir proje oluşturarak nasıl yapabileceğimizi inceleyelim;

Öncelikle MainPage.xaml dosyasını açalım ve içerisini aşağıdaki gibi değiştirerek, ekran tasarımımızı yapalım;

<Page
	x:Class="InkCanvasOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:local="using:InkCanvasOrnek">

	<Grid Background="#f1c40f" Padding="20">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="*" />
			<RowDefinition Height="Auto" />
		</Grid.RowDefinitions>

		<TextBox Header="Adınız" Grid.Row="0" />
		<TextBox Header="Soyadınız" Grid.Row="1" />
		<TextBlock Text="İmzanız" Margin="0, 4, 0, 8 " Grid.Row="2" />
		<InkCanvas x:Name="ink" Grid.Row="3" />
		<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="Kaydet" Padding="10" Grid.Row="4" />
	</Grid>

</Page>

Eğer uygulamamızı Windows 10 Mobile Emulator‘ünde açacak olursak aşağıdaki gibi gözükmeli;

Dokunmatik ekran ve Mouse ile InkCanvas‘ın kullanılabilmesi için MainPage.xaml.cs dosyasında bulunan constructor‘da InkPresenter property‘sinde yeralan InputDeviceTypes özelliğine CoreInputDeviceTypes enum’ında bulunan Mouse ve Touch değerlerini aşağıdaki şekilde eklememiz gerekli;

ink.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch;

Böylece uygulamada imza atmak için bir boşluk oluşturmuş olduk;

Eğer istersek, InkCanvas sınıfının InkPresenter property’sinde yeralan UpdateDefaultDrawingAttributes() methoduna yeni bir InkDrawingAttributes sınıfından değişken tanımlayabilir ve InkCanvas üzerine yapılan çizimlerin kalemini değiştirebiliriz;

var attr = new InkDrawingAttributes();
attr.Color = Colors.Red;
attr.PenTip = PenTipShape.Circle;
attr.Size = new Size(3, 18);
ink.InkPresenter.UpdateDefaultDrawingAttributes(attr);

Not : Taklit etmeye çalıştığım Picasso‘nun çok bilinen imzası aşağıdaki gibidir, ne dersiniz, benzetebilmiş miyim?

Windows 10 UWP Uygulamalarının Hafıza Kullanım Durumu için MemoryManager sınıfını kullanmak

08 February 2016 Yorum yapılmamış

Windows 10 UWP uygulaması geliştirirken hafıza‘nın ne kadarını kullandığınızı ve kullanabileceğiniz ne kadar hafıza alanı kaldığını bulmanız gerekebilir.

Bu durumda Windows.System namespace‘i altında yeralan MemoryManager sınıfını kullanabiliriz.

Hemen Visual Studio açarak yeni bir proje oluşturalım;

Öncelikle MainPage.xaml dosyasını açalım ve içerisine aşağıdaki kodları yazarak ekranımızı tasarlayalım;

<Page
	x:Class="MemoryManagerOrnek.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:local="using:MemoryManagerOrnek">

	<StackPanel>

		<TextBlock Text="AppMemoryUsage:" />
		<TextBlock Name="AppMemoryUsage" />
		<TextBlock Text="AppMemoryUsageLimit:" />
		<TextBlock Name="AppMemoryUsageLimit" />

	</StackPanel>

</Page>

Şimdi MainPage.xaml.cs dosyasını açalım ve DispatcherTimer sınıfından yeni bir değişken tanımlayıp, MainPage sınıfının constructor‘ında, her 1 saniyede bir tetiklenmesini sağlayalım;

DispatcherTimer timer = null;

public MainPage()
{
	this.InitializeComponent();

	timer = new DispatcherTimer();
	timer.Interval = new TimeSpan(0, 0, 1);
	timer.Tick += timer_Tick;
	timer.Start();
}

Artık timer_Tick() metodumuzu yazabiliriz;

private void timer_Tick(object sender, object e)
{
	AppMemoryUsage.Text = string.Format("{0} ({1:0.00} MB)", MemoryManager.AppMemoryUsage, MemoryManager.AppMemoryUsage / (1024.0 * 1024.0));
	AppMemoryUsageLimit.Text = string.Format("{0} ({1:0.00} GB)", MemoryManager.AppMemoryUsageLimit, MemoryManager.AppMemoryUsageLimit / (1024 * 1024 * 1024));
}

Yukarıdaki metodun içerisinde öncelikle MemoryManager sınıfının AppMemorryUsage property‘sinin değerini okuduk ve bunu (1024 x 1024) değerine bölerek kaç megabayt (MB) yaptığını hesapladık, AppMemoryUsage isimli Textblock nesnesinde gösterdik.

Aynı şekilde MemoryManager sınıfının AppMemorryUsageLimit property‘sinin değerini okuduk ve bunu (1024 x 1024 x 1024) değerine bölerek kaç gigabayt (GB) yaptığını hesapladık, AppMemoryUsageLimit isimli Textblock nesnesinde gösterdik.

Uygulama açıldıktan sonra her 1 saniyede bir, uygulamanın o anda kullandığı hafıza miktarı ve kullanabileceği hafıza miktarı ekranda gösterilecek.

Not : Eğer uygulamayı bilgisayarınızda çalıştıracak olursanız, AppMemoryUsageLimit değeri olarak, sistemde kullanılabilir boş hafıza miktarını görmelisiniz. Eğer 512 MB hafızaya sahip bir cep telefonunda çalıştıracak olursanız, 185 MB limitini, 1024 MB (1 GB) hafızalı bir cep telefonunda çalıştıracak olursanız 390 MB limit görmelisiniz.

AspNet Core 1.0 MVC6 projesine InMemory Caching desteği eklemek

07 February 2016 Yorum yapılmamış

Bu makaleyi okumadan önce Asp.Net Kategorisindeki diğer makalelerimi okumanızı tavsiye ederim.

Caching (önbellekleme) sayesinde elde etmesi uzun sürecek verilere çok daha hızlı bir şekilde ulaşabiliriz.

Hemen yeni bir Asp.Net Core 1.0 MVC 6 projesi oluşturalım ve InMemory Caching ekleyelim.

Öncelikle örnek projeyi oluşturmak istediğimiz dizine Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinden gidiyoruz ve aşağıdaki kodları çalıştırıyoruz;

yo aspnet
// Empty Application seçeneğini seçiyoruz
// Projeye inmemorycaching ismini veriyoruz

cd inmemorycaching
code .

Visual Studio Code açıldıktan sonra project.json dosyasını açıyor ve içindeki dependencies kısmına aşağıdaki satırı ekliyoruz;

"Microsoft.AspNet.Mvc": "6.0.0-rc1-final"

Böylece Empty Application tipindeki AspNet Core uygulamamıza MVC 6 paketini kullanacağımızı söylemiş olduk. Fakat paket henüz projemizin olduğu dizine indirilmedi. Bunun için Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde aşağıdaki kodu çalıştırıyoruz;

dnu restore

Artık Startup.cs dosyasını açabilir ve projemizde Mvc kullanmaya başlayabiliriz. Öncelikle ConfigureServices() methodu içerisinde uygulamamıza Mvc‘yi tanıtıyoruz;

public void ConfigureServices(IServiceCollection services)
{
	services.AddMvc();
}

Bu noktada Configure() methodu içerisinde Mvc‘yi kullanabilir, yapılandırabiliriz;

app.UseMvc(routes =>
{
	routes.MapRoute(
		name: "default",
		template: "{controller=Home}/{action=Index}"
	);
});

AspNet Core 1.0 üzerinde geliştirdiğimiz projemizde artık MVC 6 yapılandırıldı.

İlk action methodumuzu yazmak için projenin olduğu dizinde Controllers dizini oluşturalım. Bunun için aşağıdaki komutları Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde çalıştırabiliriz;

mkdir Controllers

Visual Studio Code editörüne dönerek Controllers dizininde HomeController.cs dosyasını oluşturuyoruz ve içerisine Index() methodunu aşağıdaki gibi yazıyoruz;

using Microsoft.AspNet.Mvc;

namespace inmemorycaching.Controllers
{
	public class HomeController : Controller
	{
		public string Index()
		{
			return "";
		}
	}
}

Bu noktaya kadar http://localhost:5000 adresine girdiğimizde boş bir sayfa ile karşılaşacağımız uygulamayı hazırladık.

project.json dosyasını açalım ve dependencies kısmına aşağıdaki paketi ekleyelim;

"Microsoft.Extensions.Caching.Memory": "1.0.0-rc1-final"

Command Prompt (Windows) veya Terminal (MacOS, Linux) içerisinde aşağıdaki kodu çalıştıralım;

dnu restore

Artık projemizde caching (önbellekleme) yapabiliriz. Öncelikle Startup.cs dosyasını tekrar açalım ve ConfigureServices() methodunun içini aşağıdaki gibi değiştirelim;

services.AddCaching().AddMvc();

Şimdi HomeController.cs dosyasını açıp aşağıdaki şekilde güncelleyebiliriz;

public class HomeController : Controller
{
	private IMemoryCache cache;

	public HomeController(IMemoryCache _cache)
	{
		cache = _cache;
	}

	public string Index()
	{
		var start = DateTime.Now;

		IEnumerable<int> rakamlar;

		if(!cache.TryGetValue("Rakamlar", out rakamlar))
		{
			rakamlar = Enumerable.Range(1, 10000);

			cache.Set("Rakamlar", rakamlar);
		}

		return $"10.000 öğeli listenin elde edilme süresi : {(DateTime.Now - start).TotalMilliseconds} ms.";
	}
}

Öncelikle HomeController sınıfı içinde IMemoryCache tipinde cache değişkenini tanımladık.

using kısmına Microsoft.Extensions.Caching.Memory namespace’ini eklemeyi unutmamalıyız.

HomeController sınıfının constructor‘ında IMemoryCache tipinde bir parametre aldık ve cache değişkeninde sakladık.

Index() action methodunda içerisinde 10.000 adet rakam saklayacağımız değişkenimizi tanımlıyoruz.

cache değişkeninin TryGetValue() methodu aracılığı ile liste değişkenini cache‘teki liste ile doldurmaya çalışıyoruz.

Eğer dolduramazsak, cache‘e 10.000 rakamlı değişkeni ekliyoruz.

Index() action method’unun başında ve sonunda aldığımız iki zaman değişkeni aracılığı ile arada geçen zamanı hesaplıyoruz ve ekranda gösteriyoruz.

http://localhost:5000 adresine ilk ziyaretimizde 10.000 elemanlı diziye yaklaşık 6 saniye içerisinde ulaşabildiğimizi görüyoruz.

Takip eden ziyaretlerimizde ise 0 milisaniye içerisinde aynı diziye ulaşabiliyoruz;

IMemoryCache interface‘inde tanımlı olan Set() methodu ile cache‘e eklediğimiz nesnenin belli bir süre sonra otomatik olarak cache‘ten silinmesini istiyorsak, MemoryCacheEntryOptions sınıfından yeni bir instance çıkartıp, SetAbsoluteExpiration() methoduna istediğimiz süreyi TimeSpan tipinde vermeliyiz;

cache.Set("Rakamlar", rakamlar, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30)));

Uygulamanın başlık rengini değiştirmek – Windows 10 UWP

20 July 2015 1 yorum

Windows 10 için optimize edilen uygulamaların başlık renginin (uygulamanın logosunun, isminin, kapatbüyütküçült butonlarının olduğu başlık) sistem renginden farklı olabildiğini görebiliyoruz. Örneğin Outlook, Excel, Word uygulamalarının başlık rengi uygulamanın hakim rengi ile aynıdır.

Universal Windows Platform uygulamalarında başlık rengini değiştirebilmek çok basit. Başlık rengini değiştirmek istediğiniz ekranın constructor‘ında ApplicationView sınıfının GetForCurrentView() methodunu çağırarak TitleBar özelliğine erişebiliyorsunuz.

ApplicationViewTitleBar tipindeki TitleBar özelliği içerisinde yer alan BackgroundColor, ForegroundColor, ButtonBackgroundColor ve ButtonForegroundColor özelliklerini kullanarak istediğiniz rengi belirleyebilirsiniz.

Kaynak : Customize Title Bar Colors In Windows 10 XAML Apps

Windows Phone 8 – XNA Oyunu / MiniCar

22 January 2015 Yorum yapılmamış

Bu yazımı okumadan önce Windows Phone ve XNA konusundaki diğer makalelerimi okumanızı öneririm.

Önce görseller ve oyunun arkaplan ses dosyası;

MiniCar : BackgroundMiniCar : MainCarMiniCar : Car1MiniCar : Car2MiniCar : Car3MiniCar : Car4MiniCar : Car5MiniCar : Car6MiniCar : Car7MiniCar : Car8

İlk olarak XNA Game Studio 4.0 grubundaki Windows Phone Game şablonundan MiniCarGame isimli projeyi oluşturalım;

Windows Phone : XNA Game Project Template

Game1.cs dosyasının ismini GameLoop.cs olarak değiştirdikten sonra, EnemyCar isminde yeni bir class ekleyelim;

public class EnemyCar
{
	public Texture2D Texture;

	public Vector2 Position;

	public float Velocity;

	public Rectangle Area;

	Random r = new Random();

	public EnemyCar(Texture2D CarTexture)
	{
		this.Texture = CarTexture;

		this.Position = new Vector2(r.Next(450, 850), 1);

		this.Velocity = (float)(r.NextDouble() * 4) + 3f;

		this.Area = new Rectangle((int)this.Position.X, (int)this.Position.Y, this.Texture.Width, this.Texture.Height);
	}
}

EnemyCar sınıfı sayesinde, ekrana getireceğimiz diğer araçların görsellerini, konumlarını, çarpışma testi yapabilmek için ekranda kapladığı alanı ve hızlarını bileceğiz.

GameLoop sınıfına geri dönelim ve sınıf seviyesindeki değişkenlere aşağıdakileri ekleyelim;

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

const int PENCERE_GENISLIK = 800;
const int PENCERE_YUKSEKLIK = 480;

Texture2D BackgroundTexture1;
Texture2D BackgroundTexture2;

Vector2 BackgroundPosition1 = new Vector2(0, -PENCERE_YUKSEKLIK);
Vector2 BackgroundPosition2 = new Vector2(0, 0);

Texture2D MainCarTexture;
Vector2 MainCarPosition = new Vector2(300, 300);

float KatedilenMesafe = 0f;

Rectangle ScreenArea = new Rectangle(0, 0, PENCERE_GENISLIK, PENCERE_YUKSEKLIK);
Rectangle MainCarArea = new Rectangle(300, 300, 67, 134);

TimeSpan TotalElapsedTime;

List<EnemyCar> CarList = new List<EnemyCar>();

Random r = new Random();

Texture2D[] CarTextures = new Texture2D[8];

Klavyedeki hangi tuşlara basıldığını kontrol edebilmek için KeyboardState değişkenlerimizi, arkaplanda sürekli tekrar eden ses çaldırmak için SoundEffectInstance değişkenimizi ve oyunun bittiğini takip edeceğimiz bool değişkeni de sınıf seviyesinde ekleyelim;

KeyboardState ks;
KeyboardState pks;

SoundEffectInstance BackgroundLoop;

bool IsGameOver = false;

İlk yapacağımız iş GameLoop sınıfının constructor‘ında gerekli atamaları yapmak olacak;

public GameLoop()
{
	graphics = new GraphicsDeviceManager(this);
	Content.RootDirectory = "Content";

	graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
	graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;
	graphics.IsFullScreen = true;
}

LoadContent() methodunda değişkenlerimiz aracılığıyla ses ve resim dosyalarını hafızaya yüklüyoruz;

protected override void LoadContent()
{
	spriteBatch = new SpriteBatch(GraphicsDevice);

	BackgroundTexture1 = Content.Load<Texture2D>("BackgroundRoad");
	BackgroundTexture2 = BackgroundTexture1;
	MainCarTexture = Content.Load<Texture2D>("MainCar");

	MesafeFont = Content.Load<SpriteFont>("Verdana14");

	for (int i = 0; i < CarTextures.Length; i++)
	{
		CarTextures[i] = Content.Load<Texture2D<("Car" + (i + 2));
	}

	BackgroundLoop = Content.Load<SoundEffect>("BackgroundLoop").CreateInstance();

	GameOverFont = Content.Load<SpriteFont>("GameOverFont");

	BackgroundLoop.IsLooped = true;
	BackgroundLoop.Play();
}

Update() method'unda ilk olarak oyundan çıkma ve baştan başlama durumunu sağlayacak kodları yazıyoruz;

ks = Keyboard.GetState();

if (ks.IsKeyDown(Keys.Escape))
{
	this.Exit();
}

if (IsGameOver && ks.IsKeyDown(Keys.Enter))
{
	IsGameOver = false;
	BackgroundLoop.Play();
	KatedilenMesafe = 0f;
	MainCarPosition = new Vector2(600, 600);
	MainCarArea.X = (int)MainCarPosition.X;
	MainCarArea.Y = (int)MainCarPosition.Y;
	CarList.Clear();
}

Eğer oyun sonlanmadıysa, klavyedeki tuşların durumuna göre arabamızı hareket ettiriyoruz, en son araba eklediğimiz zamandan itibaren belli bir sürenin üzerinde geçtiyse yeni EnemyCar ekliyoruz, EnemyCar listesindeki her bir arabayı hareket ettiriyoruz, yol görselini içeren arkaplanı hareket ettiriyoruz, katedilen mesafeyi güncelleyip, bizim arabamız ile diğer arabaların çarpışma testini yapıyoruz;

if (!IsGameOver)
{
	if (ks.IsKeyDown(Keys.Left))
	{
		MainCarPosition.X -= 3;
		MainCarArea.X -= 3;
	}
	if (ks.IsKeyDown(Keys.Right))
	{
		MainCarPosition.X += 3;
		MainCarArea.X += 3;
	}
	if (ks.IsKeyDown(Keys.Up))
	{
		MainCarPosition.Y -= 3;
		MainCarArea.Y -= 3;
	}
	if (ks.IsKeyDown(Keys.Down))
	{
		MainCarPosition.Y += 3;
		MainCarArea.Y += 3;
	}

	TotalElapsedTime += gameTime.ElapsedGameTime;

	if (TotalElapsedTime > TimeSpan.FromMilliseconds(1500))
	{
		EnemyCar car = new EnemyCar(CarTextures[r.Next(0, 8)]);

		CarList.Add(car);

		TotalElapsedTime = TimeSpan.Zero;
	}

	foreach (EnemyCar car in CarList)
	{
		car.Position.Y += car.Velocity;
		car.Area.Y = (int)car.Position.Y;
	}

	BackgroundPosition1.Y += 2;
	BackgroundPosition2.Y += 2;

	if (BackgroundPosition2.Y > PENCERE_YUKSEKLIK)
	{
		BackgroundPosition1.Y = -PENCERE_YUKSEKLIK;
		BackgroundPosition2.Y = 0;
	}

	KatedilenMesafe += 0.005f;

	foreach (EnemyCar car in CarList)
	{
		if (car.Area.Intersects(MainCarArea))
		{
			IsGameOver = true;
			BackgroundLoop.Stop();
		}
	}
}

Son olarak Update() methodunun son satırında KeyboardState‘i pks değişkenine atyoruz;

pks = ks;

Draw() methodunda kendi arabamızı, diğer arabaları ve katettiğimiz mesafeyi ekrana çiziyoruz;

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();

spriteBatch.Draw(BackgroundTexture1, BackgroundPosition1, Color.White);
spriteBatch.Draw(BackgroundTexture2, BackgroundPosition2, Color.White);

spriteBatch.Draw(MainCarTexture, MainCarPosition, Color.White);

spriteBatch.DrawString(MesafeFont, "Katedilen Mesafe: " + KatedilenMesafe.ToString("N2") + " km", new Vector2(51, 51), Color.Black);
spriteBatch.DrawString(MesafeFont, "Katedilen Mesafe: " + KatedilenMesafe.ToString("N2") + " km", new Vector2(50, 50), Color.White);

foreach (EnemyCar car in CarList)
{
	spriteBatch.Draw(car.Texture, car.Position, Color.White);
}

if (IsGameOver)
{
	spriteBatch.DrawString(GameOverFont, "GAME OVER", new Vector2(433, 353), Color.Yellow);
	spriteBatch.DrawString(GameOverFont, "GAME OVER", new Vector2(430, 350), Color.Red);
}

spriteBatch.End();