WPF مخفف Windows Presentation Foundation است که برای ایجاد رابط کاربری(UI) برای برنامه های دسکتاپ مورد استفاده قرار می گیرد. WPF علاوه بر این که مانند Windows Form قابلیت کشیدن و انداختن کنترل ها روی فرم ها را دارد، ویژگی های جدیدی مانند رابط کاربری غنی، انیمیشن و موارد دیگر را برای افزایش سرعت توسعه ارائه میدهد. یک موتور گرافیکی دو بعدی و سه بعدی است. به طور خلاصه کارهای زیر را می توان با استفاده از WPF انجام داد: - می تواند کنترل ها و گرافیک های معمولی ایجاد کند. - می تواند به راحتی فایل های صوتی و تصویری را بارگذاری / پخش کند. - می تواند جلوه های گرافیکی نرم مانند سایه ها(Shadows) و گرادیان رنگ(Color Gradients) را ارائه دهد. - می تواند از استایل های مشترک در کنترل های یکسان برای ارائه تم، پوسته و طرح یکسان استفاده کند. - می تواند فرم اشیاء از جمله اشکال، کنترل ها و ویدئو را تغییر دهد. - می تواند گرافیک های سه بعدی متحرک ایجاد کند. - میتواند به راحتی گرافیکهای برداری ترسیم کند.

الگوی MVVM کد UI را به 3 قسمت اصلی تقسیم می کند: Model (مدل): این لایه شامل بخش ارتباط با دیتابیس، منطق بیزنسی (کسبوکار) و یکسری کلاس های برنامه است و به هیچ وجه مستقیم با رابط کاربری تعامل ندارد. View (نما): همان رابط کاربری برنامه است که توسط زبان نشانهگذاری XAML تعریف میشود. View فقط مسئول نمایش دادهها و دریافت تعاملات کاربر است و منطق برنامه در آن وجود ندارد. این لایه با ViewModel از طریق مکانیزمهایی مانند دادهبایندینگ (Data Binding) ارتباط برقرار میکند. ViewModel (مدلنما): میانجی بین Model و View است که دادههای مدل را به فرم قابل استفاده در View تبدیل میکند. ViewModel دارای پراپرتی ها و کامندهایی است که در View تعریف میشود. این لایه منطق واکنش به تعاملات کاربر را مدیریت میکند، بدون اینکه مستقیماً به View وابسته باشد.

MVC مخفف Model-View-Controller و MVVM مخفف Model-View-ViewModel است. در MVVM، ما از ViewModel به جای Controller استفاده می کنیم. این ViewModel در زیر لایه UI وجود دارد و مسئول فراهم نمودن داده های مورد نیاز View است. مانند یک Container عمل می کند که View، توابع و داده های خود را از آن دریافت می کند.

روش پیادهسازی در WPF: • تعریف مدل دادهها، شامل کلاس ها، ارتباط با دیتابیس و پیاده سازی منطق برنامه در کلاسهای Model. • ساخت ViewModel با پیادهسازی اینترفیس INotifyPropertyChanged برای اطلاعرسانی تغییرات به View. • استفاده از Data Binding برای متصل کردن View به ViewModel (معمولاً DataContext ویندوز یا UserControl به ViewModel تنظیم میشود). • استفاده از Command ها به جای پیاده سازی Event Handlerها در کد پشت فرم (با استفاده از اینترفیس ICommand در ViewModel). • استفاده از ObservableCollection برای لیستها جهت اطلاعرسانی اتوماتیک تغییرات به View.

View:
<Window x:Class="SimpleMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Simple MVVM with Command" Height="200" Width="300">
<Window.DataContext>
<local:PersonViewModel />
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding Name}" Margin="0,10,0,0" />
<Button Content="Change Name" Command="{Binding ChangeNameCommand}" Margin="0,20,0,0"/>
</StackPanel>
</Window>
-------------------------------------------------------------------------------------------------
Model:
public class Person
{
public string Name { get; set; }
}
-----------------------------------------------------------------------------------------------------------------------------------------
ViewModel:
using System.ComponentModel;
using System.Windows.Input;
public class PersonViewModel : INotifyPropertyChanged
{
private Person _person;
public PersonViewModel()
{
_person = new Person { Name = "John" };
ChangeNameCommand = new RelayCommand(ChangeName);
}
public string Name
{
get { return _person.Name; }
set
{
if (_person.Name != value)
{
_person.Name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public ICommand ChangeNameCommand { get; }
private void ChangeName()
{
Name = "Changed Name";
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
-------------------------------------------------------------------------------------------
RelayCommand Code:
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter) => _canExecute == null || _canExecute();
public void Execute(object parameter) => _execute();
}
این سوال از من پرسیده شده است  + 
1- توسعه آسانتر و همکاری بهتر با جداسازی View و ViewModel، طراحان رابط کاربری (UI Designers) و برنامهنویسان بکاند میتوانند به صورت همزمان و مستقل بر روی بخشهای مختلف پروژه کار کنند. این تقسیم کار موجب افزایش بهرهوری و تسهیل همکاری تیمی میشود. 2- تستپذیری بهتر چون ViewModel و Model کاملاً از View جدا هستند، میتوان کدهای منطق برنامه (ViewModel و Model) را بدون نیاز به رابط کاربری تست کرد. این امر نوشتن تستهای واحد را آسانتر میکند و کیفیت کد را بالا میبرد. 3- نگهداری و توسعه آسانتر جداسازی دقیق کدها باعث میشود که تغییرات در یک بخش (مثلاً طراحی UI یا منطق بیزنسی) بدون تأثیر منفی بر بخش دیگر انجام شود. این مزیت باعث میشود نگهداری و افزودن ویژگیهای جدید سادهتر و سریعتر شود. 4- خوانایی کد و سازماندهی بهتر ساختار واضح MVVM کد منظمتر و قابل فهمتری ایجاد میکند. این موضوع به توسعهدهندگان این امکان را میدهد که به سرعت در کدها نفوذ کنند و تغییرات لازم را انجام دهند. 5- قابلیت استفاده مجدد کد ViewModel و Model میتوانند در بخشهای مختلف برنامه یا حتی پروژههای دیگر دوباره استفاده شوند که باعث کاهش حجم کد و تلاش توسعه میگردد. 6- کاهش وابستگیها و Losse Coupling با کاهش وابستگیهای مستقیم بین بخشهای مختلف برنامه (View، ViewModel، Model)، انعطافپذیری و قابلیت تغییر سیستم افزایش مییابد. 7- پشتیبانی بهتر از ویژگیهای WPF MVVM به خوبی با ویژگیهایی مانند Data Binding و Commands در WPF هماهنگ است که توسعه رابطهای کاربری داینامیک و واکنشگرا را راحتتر میکند.

PRISM چارچوبی برای ایجاد برنامه های پیچیده برای WPF ، Silverlight یا Windows Phone است. PRISM از MVVM ، IC ، Command Pattern ، DI و Sepration of Concerns برای Losse Coupling استفاده می کند.

1- Prism یک کلاس پایه به اسم BindableBase دارد که ViewModel ها میتوانند به سادگی با ارث بری از این کلاس و استفاده از متد SetProperty بدون نیاز به پیاده سازی اینترفیس INotifyPropertyChanded از تغییرات UI مطلع شوند. 2- Prism یک کلاس DelegateCommand داده که به راحتی میتوان کامندها (ICommand) را در ViewModel پیاده کرد و نیازی نیست برای پیاده سازی کد ICommand کلاسی اضافه کنید. 3- در MVVM باید View به ViewModel وصل شود. Prism این کار را به صورت خودکار با ViewModelLocator انجام میدهد. یعنی زمانی که فرم MainWindow را دارید، Prism دنبال یک ویومدل به نام MainWindowViewModel می گردد و اتصال را برقرار میکند و نیازی به ست کردن دستی DataContext نیست. فقط باید نامگذاری فرم ها و ویومدل ها مشابه هم باشند. 4- در MVVM ویومدلها معمولاً به سرویسها و مدلها نیاز دارند. Prism دارای یک Container (مثلاً Unity یا DryIoc) است که وابستگیها رو تزریق می کند. اینکار باعث میشود ویومدل تستپذیر شود و وابستگیها از بیرون داده شوند.

1- ViewModel implementation
public class MainWindowViewModel : BindableBase
{
private string _title = "سلام";
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
}
-----------------------------------------------------------
2- DelegateCommand
public DelegateCommand ClickCommand { get; }
public MainWindowViewModel()
{
ClickCommand = new DelegateCommand(OnClick);
}
private void OnClick()
{
// منطق کلیک
}
-----------------------------------------------
3- Setting DataContext
<Window x:Class="WpfApp1.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:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:local="clr-namespace:WpfApp1"
xmlns:vm="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="650" Width="800">
<!--<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>-->
-------------------------------------------------------------------------
4- Dependency Injection
public interface IGreetingService
{
string GetGreeting();
}
public class GreetingService : IGreetingService
{
public string GetGreeting()
{
return "سلام از سرویس!";
}
}
using Prism.Mvvm;
public class MainWindowViewModel : BindableBase
{
private readonly IGreetingService _greetingService;
private string _message;
public string Message
{
get => _message;
set => SetProperty(ref _message, value);
}
// سرویس از طریق DI به ویومدل تزریق میشود
public MainWindowViewModel(IGreetingService greetingService)
{
_greetingService = greetingService;
Message = _greetingService.GetGreeting();
}
}
این سوال از من پرسیده شده است  + 
در WPF انواع Layout Panel وجود دارند که به شما کمک میکنند چیدمان (Layout) عناصر UI را مدیریت کنید. لیست این پنل ها به صورت زیر می باشد: 1- StackPanel: عناصر را به صورت ستونی یا ردیفی پشت سر هم قرار میدهد. جهت چیدمان با `Orientation="Vertical"` یا `Orientation="Horizontal"` مشخص میشود. 2- WrapPanel: عناصر را پشت سر هم میچیند و وقتی به انتهای فضا رسیدند، به خط بعدی منتقل میشوند. 3- DockPanel: هر عنصر میتواند به سمت **Top, Bottom, Left, Right** داک شود. عنصر آخر میتواند فضا را پر کند (`LastChildFill="True"`). 4- Grid: قویترین و پرکاربردترین Layout که عناصر را در سطرها و ستونها (Rows & Columns) قرار میدهد. امکان `RowSpan` و `ColumnSpan` وجود دارد. 5- Canvas: مکان دقیق هر عنصر با `Canvas.Left` و `Canvas.Top` مشخص میشود. 6- UniformGrid: مشابه Grid ولی همه خانهها هماندازه هستند وتعداد ردیف و ستون قابل تنظیم است. نکته های کلیدی: - انتخاب Layout Panel مناسب باعث میشود رابط کاربری انعطافپذیر و قابل تغییر اندازه باشد. - برای ساخت رابط های کاربری پیچیده معمولاً از ترکیب انوام پنل ها مثل Grid + StackPanel یا DockPanel استفاده میشود.

1- StackPannel:
<StackPanel Orientation="Vertical">
<Button Content="Button 1"/>
<Button Content="Button 2"/>
</StackPanel>
--------------------------------------------------------
2- WrapPannel:
<WrapPanel Orientation="Horizontal">
<Button Content="1"/>
<Button Content="2"/>
<Button Content="3"/>
</WrapPanel>
--------------------------------------------------------------
3- DockPannel:
<DockPanel LastChildFill="True">
<Button Content="Top" DockPanel.Dock="Top"/>
<Button Content="Left" DockPanel.Dock="Left"/>
<Button Content="Center"/>
</DockPanel>
-------------------------------------------------------------------------
4- Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="Button1"/>
<Button Grid.Row="1" Grid.Column="1" Content="Button2"/>
</Grid>
------------------------------------------------------------------------------------
5- Canvas:
<Canvas>
<Button Canvas.Left="50" Canvas.Top="30" Content="Button1"/>
</Canvas>
------------------------------------------------------------
6- UniformGrid:
<UniformGrid Rows="2" Columns="2">
<Button Content="1"/>
<Button Content="2"/>
<Button Content="3"/>
<Button Content="4"/>
</UniformGrid>
این سوال از من پرسیده شده است  + 
برای اینکه کنترل ها روی صفحه نمایش هایی با اندازه های مختلف یا اندازه فونت های مختلف درست قرار بگیرند، باید از پنل ها استفاده کنیم.. اگر ما کنترل ها را روی مختصات پیکسلی قرار دهیم ، در صورت انتقال به یک محیط دیگر ، UI برنامه به هم میریزد. به همین دلیل ، Layout Pannel ها ضروری هستند.

تمام پراپرتی های عناصر UI از نوع Dependency Property هستند. به طور مثال خاصیت IsMouseOver یک Dependency Property است. با استفاده از این پراپرتی ها میشه به کنترل های UI استایل داد، داده بایند کرد، ریسورس اضافه کرد و ... . شما میتوند به کنترل مورد نظر خودتون یک DependencyProperty جدید اضافه کنید. در مثال زیر یک UserControl را میبینید که به آن یک Dependency Property به نام SetText اضافه شده است.

using System;
using System.Windows;
namespace WpfApplication3
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public static readonly DependencyProperty SetTextProperty = DependencyProperty.Register(
"SetText",
typeof(string),
typeof(UserControl1),
new PropertyMetadata(default(string), OnSetTextChanged));
public string SetText
{
get { return (string)GetValue(SetTextProperty); }
set { SetValue(SetTextProperty, value); }
}
private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Handle the change in the SetText property here
}
}
}
*****************
<UserControl
x:Class="WpfPlayground.Views.UserControls.UserControl1 "
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<Grid>
<TextBlock Text="{Binding SetText}"/>
</Grid>
</UserControl>
****************
<Window
x:Class="WpfPlayground.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:controls="clr-namespace:WpfPlayground.Views.UserControls"
mc:Ignorable="d"
Title="SourceSara.Com"
Height="400"
Width="600">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<controls:UserControl1 SetText="Hello World"/>
</Grid>
</Window>
این سوال از من پرسیده شده است  + 
بله ، Windows From را می توان در WPF استفاده کرد. با استفاده از کنترل WindowsFormsHost که از قبل نصب شده است ، کنترل های ویندوز فرم می تواند در کنار کنترل های WPF در یک صفحه قرار بگیرد.

<Window x:Class="WpfWinFormsDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
Title="WPF with WinForms" Height="300" Width="400">
<Grid>
<wfi:WindowsFormsHost>
<wf:Button Text="WinForms Button"/>
</wfi:WindowsFormsHost>
</Grid>
</Window>
این سوال از من پرسیده شده است  + 
CustomControl در WPF برای تغییر یا توسعه کنترل های موجود مورد استفاده قرار می گیرد و کنترلی است که: از یک کلاس پایه (مانند Control یا Button) ارثبری میکند. ظاهر (UI) آن با استفاده از ControlTemplate در Themes/Generic.xaml تعریف میشود. قابل استفاده مجدد، قابل تغییر استایل و قابل سفارشیسازی در هر پروژه است. معمولاً برای کتابخانهها و کنترلهای حرفهای (مثل Telerik, DevExpress, RadControls) استفاده میشود. نکته مهم: در صورتی که تغییر یک کنترل فقط محدود به افزودن یک پراپرتی باشدو ظاهر کنترل عوض نشود، نیازی به افزودن ControlTemplate وجود ندارد. در مثال زیر قصد داریم یک Custom Control ایجاد کنیم که کنترل TextBox را توسعه دهد و به آن پراپرتی PlaceHolder اضافه کند.

public class CustomTextBox : TextBox
{
public string Placeholder
{
get { return (string)GetValue(PlaceholderProperty); }
set { SetValue(PlaceholderProperty, value); }
}
public static readonly DependencyProperty PlaceholderProperty =
DependencyProperty.Register("Placeholder", typeof(string), typeof(CustomTextBox),
new PropertyMetadata("Enter text..."));
static CustomTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomTextBox),
new FrameworkPropertyMetadata(typeof(CustomTextBox)));
}
}
-------------------------------------------------------
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCustomControlDemo">
<Style TargetType="{x:Type local:CustomTextBox}">
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomTextBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
-------------------------------------------------------
<StackPanel Margin="20">
<TextBlock Text="Custom TextBox:" Margin="0 0 0 5"/>
<local:CustomTextBox Placeholder="Type something..." Width="200"/>
</StackPanel>
این سوال از من پرسیده شده است  + 
رابط INotifyPropertyChanged یکی از مهمترین اجزا در WPF و MVVM است و برای اعلام تغییر مقدار پراپرتیها به رابط کاربری (UI) استفاده میشود. این اینترفیس یک رویداد(Event) به نام PropertyChanged دارد، هرگاه مقداری در ViewModel تغییر کند، باید این رویداد را فراخوانی کنیم تا UI بتواند بهصورت خودکار بهروزرسانی شود.

using System.ComponentModel;
public class PersonViewModel : INotifyPropertyChanged
{
private string name;
public string Name
{
get => name;
set
{
if (name != value)
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
این سوال از من پرسیده شده است  + 
Event و Command هر دو برای پاسخ به تعامل کاربر با UI استفاده میشوند، اما تفاوتهای اساسی دارند: Event (رویداد): در صورتی اجرا میشود که رویدادی در UI رخ دهد، مثل کلیک دکمه یا تغییر متن، که معمولاً کد آن در پشت فرم مربوطه(Code-Behind) اضافه میشود. این روش خلاف معماری MVVM عمل میکند چون View به طور مستقیم با کد در ارتباط است در حالی که باید کل کد مربوط به فرم باید در ViewModel باشد. Command (دستورات): در این حالت تمام کدی که برای یک رویداد در نظر گرفته شده است با استفاده از Command در ViewModel نوشته میشود. در واقع در این حالت کد مربوط به آن رویداد به پراپرتی Command در UI بایند میشود. این روش به پیاده سازی درست معماری MVVM کمک میکند.

Event:
//UI
<Button Content="Click Me" Click="Button_Click" />
// Code-behind
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button clicked");
}
------------------------------------------------------------
Command
//UI code
<Button Content="Click Me" Command="{Binding ClickCommand}" />
//ViewModel Code
public class MyViewModel
{
public DelegateCommand ClickCommand { get; }
public MyViewModel()
{
ClickCommand = new DelegateCommand(OnButtonClicked);
}
private void OnButtonClicked()
{
// منطق دکمه
}
}
این سوال از من پرسیده شده است  + 
زمانی که قصد دارید چندین بار از یک بخش UI در جاهای مختلف استفاده کنید، به جای کپیکردن کد، آن بخش را در قالب UserControl تعریف میکنید.میتوانید چندین کنترل ساده (مثل Button, TextBox, Label و …) را داخل یک UserControl قرار بدهید و آن را به صورت یک کنترل جدید قابلاستفاده مجدد (Reusable) در کل پروژه یا حتی پروژههای دیگر استفاده کنید. در مثال زیر قصد داریم لیستی از کاربرها را با نام و ایمیل در UI نشان دهیم، برای اینکار یک UserControl طراحی میکنیم:

//UserControl code
<UserControl x:Class="WpfApp1.UserInfoControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="250">
<StackPanel Margin="5">
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
<TextBlock Text="{Binding Email}" Foreground="Gray"/>
</StackPanel>
</UserControl>
//UserControl's data model
public class User
{
public string Name { get; set; }
public string Email { get; set; }
}
//ViewModel
using System.Collections.ObjectModel;
public class MainViewModel
{
public ObservableCollection<User> Users { get; set; }
public MainViewModel()
{
Users = new ObservableCollection<User>
{
new User { Name = "Ali", Email = "ali@test.com" },
new User { Name = "Sara", Email = "sara@test.com" },
new User { Name = "Reza", Email = "reza@test.com" }
};
}
}
//MainWindow
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
Title="MainWindow" Height="350" Width="400">
<Grid>
<ItemsControl ItemsSource="{Binding Users}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- هر آیتم لیست یک UserControl میشود -->
<local:UserInfoControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
این سوال از من پرسیده شده است  + 
در WPF وقتی میگوییم Resource (منبع)، منظور اشیائی است که در XAML یا کد تعریف میکنیم تا بتوانیم آنها را چندبار و در بخشهای مختلف برنامه استفاده کنیم، بدون اینکه مجبور باشیم دوباره و دوباره همان شیء را از جایی بخوانیم یا ایجاد کنیم. با استفاده از پراپرتی x:Key، به Rsourceیک کلید داده میشود، شما می توانید با استفاده از این کلید از سایر قسمتهای برنامه به آن Resource دسترسی پیدا کنید. در مثال زیر، فقط یک رشته سادهی متنی در Resource ذخیره شده است و سپس در دو کنترل مختلف TextBlock از آن رشته استفاده شده است.

<Window x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="ResourceSample" Height="150" Width="350">
<Window.Resources>
<sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
<TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock>
</StackPanel>
</Window>
این سوال از من پرسیده شده است  + 
در WPF عمدتا دو نوع Resource وجود دارد: 1- Static Resource: - در زمان کامپایل (Load اولیه) مقداردهی میشود. - بعد از بارگذاری تغییر نمیکند. - معمولاً برای رنگها، استایلها، قالبها، اشیاء و مقادیر ثابت استفاده میشود. 2- Dynamic Resource: - در زمان اجرا (RunTime) مقداردهی میشود. - اگر مقدار منبع تغییر کند، کنترلهایی که از آن استفاده میکنند نیز بهروزرسانی میشوند. در کد زیر دو مثال داریم. اولی برای Static Resource و دومی برای Dynamic Resource. همانطوری که در مثال دوم می بینید، با کلیک روی یک دکمه (button) میتوان محتوای منبع را تغییر داد.

Static Resource Example:
<Grid.Resources>
<SolidColorBrush x:Key="lblbgcolor" Color="Blue"/>
</Grid.Resources>
<Label Name="lbl" Margin="71,44,77,0" Background="{StaticResource lblbgcolor}" Height="49" />
----------------------------------------------------------------------------
Dynamic Resource Example:
<Window.Resources>
<SolidColorBrush x:Key="brush" Color="Red" />
</Window.Resources>
<Button x:Name="btn" Content="Click Me" Click="Button_Click" Background="{DynamicResource brush}" Height="100" Width="100" />
*Code Behind
private void Button_Click(object sender, RoutedEventArgs e)
{
this.btn.SetResourceReference(BackgroundProperty, "brush");
}
این سوال از من پرسیده شده است  + 
از ValueConverter برای بایند کردن داده در زمانی استفاده می شود نوع داده ارسالی شما با نوع مورد انتظار متفاوت است. به عنوان مثال شما میخواهید یک CheckBox را بر اساس یک مقدار علامت بزنید، اما مقدار به جای مقدار بولی، رشتهای مانند «بله» یا «نه» است. یا اینکه شما یک TextBox و یک Button دارید و می خواهید هنگامی که متن TextBox پر/خالی است Button را فعال/غیرفعال کنید. در این حالت شما باید داده های رشته را به بولی تبدیل کنید. این امر با استفاده از Value Converer امکان پذیر است. برای پیاده سازی Value Converter ، باید از IValue Converter در فضای نام System.Windows.Data ارث بری کرده و متدهای Convert و Convert Back پیاده سازی کنید. در مثال زیر می خواهیم یک Converter ساده را پیاده سازی کنیم که یک رشته را به عنوان ورودی می گیرد و سپس یک مقدار بولی را برمی گرداند، و همچنین برعکس.

<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
Title="ConverterSample" Height="140" Width="250">
<Window.Resources>
<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
</Window.Resources>
<StackPanel Margin="10">
<TextBox Name="txtValue" />
<WrapPanel Margin="0,10">
<TextBlock Text="Current value is: " />
<TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
</WrapPanel>
<CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
</StackPanel>
</Window>
*Code Behind
public class YesNoToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
switch(value.ToString().ToLower())
{
case "yes":
return true;
case "no":
return false;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value is bool)
{
if((bool)value == true)
return "yes";
else
return "no";
}
return "no";
}
}
این سوال از من پرسیده شده است  + 
ICommand یک اینترفیس است که به شما اجازه میدهد عملیاتی کلیک را به ViewModel متصل کنید بدون اینکه نیاز باشد مستقیم در Code-Behind رویداد (Event) بنویسید. این اینترفیس در پیاده سازی الگوی MVVM نقش اساسی دارد و Method Binding با استفاده از اینترفیس انجام میشود. برای مثال فرض کنید یک TextBox و یک Button در UI داریم. میخواهیم وقتی کاربر متنی را می نویسد و روی Button کلیک می کند، پیام در کادر نمایش داده شود. در این صورت کد مربوط به نمایش متن به جای Code Behind داخل یک متد در View Model پیاده سازی میشود. اینترفیس ICommand دارای دو متد و یک Event است: - Execute(object): این متد زمانی فراخوانی می شود که یک Command اجرا شود. - CanExecute(object): مشخص میکند آیا Command در حال حاضر قابل اجراست یا نه. - CanExecuteChanged: وقتی وضعیت اجرا تغییر کند (مثلاً دکمه باید فعال/غیرفعال شود) این رویداد فراخوانی میشود.

public interface ICommand
{
void Execute(object parameter);
bool CanExecute(object parameter);
event EventHandler CanExecuteChanged;
}
این سوال از من پرسیده شده است  + 
Data binding فرآیند ارسال اطلاعات از یک شی به شی دیگر و نمایش آن در یک یا چند عنصر در رابط کاربری(User Interface) است. سینتکس (Syntax) کلی Binding به صورت زیر است: {Binding Path=NameOfProperty} در Path ویژگی(Property) را که میخواهید به آن متصل شوید را قرار میدهید، با این حال، از آنجایی که Path ویژگی پیشفرض یک binding است، در صورت تمایل میتوانید آن را حذف کنید، مانند این: {Binding NameOfProperty} با این حال، Binding ویژگی های بسیار دیگری دارد، یکی از آنها ElementName است که در مثال زیر استفاده کردیم و این به ما امکان می دهد که مستقیماً به عنصر UI دیگری به عنوان منبع متصل شویم. هر ویژگی که در binding تنظیم می کنیم با یک کاما از هم جدا می شود: {Binding Path=Text, ElementName=txtValue}

<Window x:Class="WpfTutorialSamples.DataBinding.HelloBoundWorldSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="HelloBoundWorldSample" Height="110" Width="280">
<StackPanel Margin="10">
<TextBox Name="txtValue" />
<WrapPanel Margin="0,10">
<TextBlock Text="Value: " FontWeight="Bold" />
<TextBlock Text="{Binding Path=Text, ElementName=txtValue}" />
</WrapPanel>
</StackPanel>
این سوال از من پرسیده شده است  + 
Control Template ظاهر بصری یک کنترل را تعریف می کند. همه عناصر رابط کاربری دارای نوعی ظاهر و همچنین رفتار هستند، به عنوان مثال، دکمه ظاهر و رفتار دارد. رویداد Click یا رویداد Mouse Hover ماوس رفتارهایی هستند که در پاسخ به کلیک و یا قرار گرفتن ماوس روی کنترل اتفاق می افتند و همچنین ظاهر پیشفرض دکمه وجود دارد که میتوان همه آن ها را با Control Template تغییر داد. برای مثال میتوانید با استفاده از این قابلیت شکل یک Button را از مستطیل به دایره تغییر دهید یا کاری کنید که وقتی ماوس روی Button رفت رنگ آن تغییر کند. در مثال زیر می توانید تفاوت بین یک Button معمولی با یک Button که از Control Template استفاده کرده است مشاهده کنید.

<Window x:Class = "TemplateDemo.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "MainWindow" Height = "350" Width = "604">
<Window.Resources>
<ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
<Grid>
<Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4">
<GradientStop Offset = "0" Color = "Red" />
<GradientStop Offset = "1" Color = "Orange" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter Content = "{TemplateBinding Content}"
HorizontalAlignment = "Center" VerticalAlignment = "Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property = "IsMouseOver" Value = "True">
<Setter TargetName = "ButtonEllipse" Property = "Fill" >
<Setter.Value>
<LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4">
<GradientStop Offset = "0" Color = "YellowGreen" />
<GradientStop Offset = "1" Color = "Gold" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property = "IsPressed" Value = "True">
<Setter Property = "RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX = "0.8" ScaleY = "0.8"
CenterX = "0" CenterY = "0" />
</Setter.Value>
</Setter>
<Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<Button Content = "Round Button!"
Template = "{StaticResource ButtonTemplate}"
Width = "150" Margin = "50" />
<Button Content = "Default Button!" Height = "40"
Width = "150" Margin = "5" />
</StackPanel>
</Window>
این سوال از من پرسیده شده است  + 
با استفاده از استایلها، میتوانید مجموعهای از پراپرتی های پیش فرض یک کنترل را مانند رنگ و سایز و ... را گروهبندی کنید به آنها مقدار دلخواه خود را بدهید و به کنترلهای خود اختصاص دهید.

<Window x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SimpleStyleSample" Height="200" Width="250">
<StackPanel Margin="10">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="24" />
</Style>
</StackPanel.Resources>
<TextBlock>Header 1</TextBlock>
<TextBlock>Header 2</TextBlock>
<TextBlock Foreground="Blue">Header 3</TextBlock>
</StackPanel>
</Window>
این سوال از من پرسیده شده است  + 
Style در WPF برای تغییر دادن ظاهر کلی (Properties) یک کنترل استفاده میشود. یعنی میتوانی مجموعهای از Setter ها بنویسی که مثلاً رنگ، فونت، حاشیه و … یک کنترل رو مشخص کنه ولی رفتار کنترل تغییر نمیکنه، فقط تنظیمات ظاهری روی هم جمع میشن. Template در WPF کنترل رو از صفر ترسیم میکنه. با Template میتونی شکل ظاهری یک کنترل (مثلاً Button یا ListBoxItem) رو کاملاً بازنویسی کنی. دو نوع Template داریم: 1- ControlTemplate: ظاهر یک کنترل را بازنویسی میکنه. 2- DataTemplate: شکل نمایش دادهها در کنترلهای ItemsControl (مثل ListBox, ComboBox) رو مشخص میکنه.

:Style
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="DarkBlue"/>
<Setter Property="FontSize" Value="16"/>
</Style>
</Window.Resources>
<Button Content="Click Me"/>
---------------------------------------------------------------------
Template:
<Window.Resources>
<ControlTemplate TargetType="Button" x:Key="RoundButtonTemplate">
<Border Background="LightGreen" CornerRadius="20" Padding="10">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Window.Resources>
<Button Content="Click Me" Template="{StaticResource RoundButtonTemplate}"/>
این سوال از من پرسیده شده است  + 
DataTemplate مخصوص دادههاست (Data). تعیین میکند یک شیء داده وقتی در UI نمایش داده می شود، چطور دیده شود. بیشتر در کنترلهای ItemsControl (مثل ListBox, ComboBox, ListView) استفاده می شود. در واقع ممی گویدگه: "هر آیتم داده را چطور نمایش بدهم؟" ControlTemplate مخصوص کنترلها (Control) است. تعیین میکند ظاهر (UI) خودِ کنترل چطور ساخته شود. برای بازنویسی کامل ظاهر یک کنترل (مثل Button, CheckBox, Slider و …) استفاده می شود. در واقع می گوید: "خود این کنترل چه شکلی داشته باشد؟

<Window.Resources>
<DataTemplate x:Key="PersonTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" FontWeight="Bold"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding LastName}" Foreground="Gray"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding People}" ItemTemplate="{StaticResource PersonTemplate}"/>
-------------------------------------------------------------------------------
<Window.Resources>
<ControlTemplate TargetType="Button" x:Key="RoundButtonTemplate">
<Border Background="LightBlue" CornerRadius="15" Padding="10">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Window.Resources>
<Button Content="Click Me" Template="{StaticResource RoundButtonTemplate}"/>
این سوال از من پرسیده شده است  + 
Trigger به معنی "راهانداز" یا "شرط فعالساز" است. در WPF از Trigger استفاده میکنیم تا وقتی یک شرط روی کنترل برقرار شد، یک سری Property یا Action روی آن کنترل اعمال شود. یعنی اگر فلان شرط برقرار شد، این تغییرات را روی UI اجرا کن. سه مدل Tigger وجود دارد: 1- Property Trigger: وقتی مقدار یک Property تغییر میکنه، فعال میشه. 2- Data Trigger: وقتی یک مقدار داده (Binding) شرطی را برقرار کند، فعال می شود. معمولاً در DataTemplate یا Style استفاده می شود. 3- Event Trigger: وقتی یک رویداد (Event) اتفاق بیفتد، فعال می شود.

Property Tigger:
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGreen"/>
</Trigger>
</Style.Triggers>
</Style>
-----------------------------------------------------------------------------
Data Trigger:
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOnline}" Value="True">
<Setter Property="Foreground" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
-------------------------------------------------------------------------------
Event Trigger:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
<Grid>
<TextBox Width="200">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedCommand}"
CommandParameter="{Binding Text, RelativeSource={RelativeSource AncestorType=TextBox}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Grid>
</Window>
این سوال از من پرسیده شده است  + 
Blazor یک فریمورک (Framework) از مایکروسافت است که به شما اجازه میدهد اپلیکیشنهای وب را با زبان C# بسازید، بدون نیاز به جاوا اسکریپت برای منطق اصلی. اپ Blazor از کامپوننتها ساخته میشود. هر کامپوننت یک فایل .razor است که میتواند HTML و C# را ترکیب کند. در WPF خود Blazor اجرا نمیشود، اما میتوان آن را داخل WPF ادغام کرد. در صورتی که از Net Framework. استفاده می کنید، باید یک کنترل مرورگر به نام WebView2 به فایل XAML اضافه کنید و برنامه Blazor را داخل آن لود کنید. در صورتی که از Net 6. به بالا استفاده می کنید، کامپوننتهای Blazor مستقیماً در پروسه WPF اجرا میشوند. نیازی به مرورگر جداگانه نیست، فقط از کنترل BlazorWebView استفاده میکنید.

A simple Blazor component
<h3>سلام از Blazor!</h3>
@code {
private string Message = "این یک پیام از C# است";
}
-------------------------------------------------------
Load Blazor insde WebView:
<wpf:WebView2 Source="https://localhost:5001" />
-------------------------------------------------------
Use BlazorWebView:
<wpf:BlazorWebView HostPage="wwwroot/index.html">
<wpf:BlazorWebView.RootComponents>
<wpf:RootComponent Selector="#app" ComponentType="{x:Type local:Hello}" />
</wpf:BlazorWebView.RootComponents>
</wpf:BlazorWebView>
این سوال از من پرسیده شده است  + 
بله، با استفاده از پراپرتی CommandParameter میتوان برای Command پارامتر ورودی تعیین کرد. در مثال زیر میتوانید روش پیاده سازی آن را مشاهده کنید:

//View code
<ListBox x:Name="MyListBox" ItemsSource="{Binding Items}" />
<Button Content="حذف"
Command="{Binding DeleteCommand}"
CommandParameter="{Binding SelectedItem, ElementName=MyListBox}" />
//ViewModel code
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
public class MainViewModel
{
public ObservableCollection<string> Items { get; } = new ObservableCollection<string>
{
"سیب",
"موز",
"پرتقال",
"کیوی"
};
public ICommand DeleteCommand { get; }
public MainViewModel()
{
DeleteCommand = new RelayCommand<string>(OnDelete);
}
private void OnDelete(string item)
{
if (item != null && Items.Contains(item))
{
Items.Remove(item);
MessageBox.Show($"آیتم '{item}' حذف شد!");
}
}
}
این سوال از من پرسیده شده است  + 
دو نوع از اسناد پشتیبانی شده توسط Windows Presentation Foundation (WPF) اسناد Flow Fromat و Fix Fromat هستند. سند Flow Fromat محتوا را متناسب با اندازه صفحه تغییر می دهد در حالی که سند Fix Fromat محتوا را بدون توجه به اندازه صفحه نمایش می دهد.

فضای نام مورد نیاز برای کار با 3D در System.Windows.Media.Medi3D است.

خیر ، WPF هرگز نمی تواند جایگزین DirectX شود. WPF نمی تواند برای ایجاد بازی با گرافیک خیره کننده استفاده شود. WPF جایگزین فرم Windows است ، نه DirectX.

یک شی ای که حالت آن قفل شده است به طوری که تغییر ناپذیر می شود ، به عنوان یک شی Freezable شناخته می شود. چنین اشیائی عملکرد بهتری دارند. همچنین اگر آنها نیاز به اشتراک گذاری بین Therad ها داشته باشند ، ایمن تر است.

WPF یک فناوری جدیدتر است و بنابراین دارای جدیدترین ابزارهای توسعه است. این برنامه طیف گسترده ای از زبان های برنامه نویسی را پشتیبانی می کند و از قابلیت استفاده مجدد قوی برخوردار است.

Silverlight نسخه سبکتر و وبی از WPF برای ساخت اپلیکیشنهای وب است که توسط مایکروسافت در سال 2007 ارائه شد .ولی این تکنولوژی در حال حاضر منسوخ شده است و توسط مایکروسافت پشتیبانی نمی شود. بنابراین خیلی از مفاهیم آن با WPF مشترک هستن.

Pass Animation یک نوع انیمیشن است که در آن شی متحرک مسیری را طی می کند که توسط هندسه مسیر تعیین شده است.

بله ، برنامه های WPF را می توان بدون XAML ایجاد کرد ، زیرا استفاده از XAML در WPF یک امر انتخابی است.

WPF دارای سه نوع پنجره است: پنجره عادی Page Window Navigate Window

مرتب سازی را می توان با استفاده از ویژگی ItemsCollection انجام داد. ItemsCollection حاوی یک ویژگی به نام SortDescription است که نمونه های System.ComponentModel.SortDescription را در خود نگه می دارد. هر نمونه SortDescription نحوه مرتب سازی عناصر را مشخص می کند و نشان می دهد که مرتب نزولی یا صعودی است. به عنوان مثال ، این کد عناصر ContentControl را بر اساس ویژگی تعداد کلمات آنها طبقه بندی می کند: myItemsControl.Items.SortDescription.Add (new SortDescription ("WordCount" ، ListSortDirection.Descending)) ؛

هر زمان که الزامی برای ایجاد رابط کاربری سفارشی ایجاد شود ، استفاده می شود و یک کلاس برای طراحی است که دستورالعمل هایی برای ساخت یک شی می دهد. این دستورالعمل ها شامل Opacity و غیره میشوند. کلاس Visual همچنین عملکرد کلاسهای مدیریت شده WPF و MilCore.dll را تقویت می کند.

Attached Property اساساً همان Dependency Property است که امکان پیوست یک مقدار را به هر شی تصادفی می دهد.

به فرایند تبدیل یک شی به آرایه ای از بایت ها Serialization گفته میشود.

Silverlight و WPF از این نظر مشابه هستند که هر دو از XAML استفاده می کنند و کد، نحو و کتابخانه های یکسانی را به اشتراک می گذارند.

XAML مخفف eXtensible Application Markup Language است. زبانی است که برای نمونه سازی اشیاء NET. استفاده می شود. این زبان توسط مایکروسافت برای نوشتن رابط کاربری برای برنامه های نسل بعدی توسعه یافته است. XML برای ذخیره داده ها یا کار با داده های ذخیره شده طراحی شده است ، در حالی که XAML نسخه توسعه یافته XML است که برای برنامه نویسی NET. استفاده می شود.

دو نوع ترازبندی محتوا در WPF وجود دارد: HorizontalContentAlignment VerticalContentAlignment این هر دو ویژگی در کلاس System.Windows.Controls.Control تعریف شده است که کلاس اصلی همه کنترل ها در WPF است.

سوالی هست که اینجا نمیبینیش و از نظر تو مهمه؟ خودت سوالی داری که دنبال جوابشی؟ جواب بهتری واسه یکی از سوالای بالا داری؟ پس واسمون بفرست.
چه تفاوتی بین public ، static ...
Net. چیست؟
مزایای استفاده از NET. چیست؟
تفاوت بین Reference Type و Val...
برو به همه سوالات
#C چیست؟
تفاوت بین public ، static و vo...
constructor یا سازنده چیست؟
overloading در #C چیست؟
برو به همه سوالات