<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[הדגמה פשוטה של MVVM ב-C# WPF]]></title><description><![CDATA[<h1>הדגמה פשוטה של MVVM</h1>
<p dir="auto"><a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel" target="_blank" rel="noopener noreferrer nofollow ugc">עיין כאן</a> להסבר על המושג MVVM:<br />
להרחבה על הנושא <a href="https://learn.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern" target="_blank" rel="noopener noreferrer nofollow ugc">עיין כאן</a></p>
<p dir="auto">היה לי צורך להדגים את המודל mvvm עבור ידיד אז יצרתי את הפרוייקט דלהלן על בסיס <a href="https://www.codeproject.com/Articles/1052346/ICommand-Interface-in-WPF" target="_blank" rel="noopener noreferrer nofollow ugc">כתבה זו</a> (הפרוייקט רחוק מלהיות מושלם אבל הוא מספיק בשביל הדגמה לדעתי):</p>
<p dir="auto">התוכנה מיישמת מחשבון (כלשהו) שיניתי קצת מהכתבה לצורך ההדגמה.</p>
<hr />
<ol>
<li><strong>קוד ל-view</strong></li>
</ol>
<hr />
<pre><code>&lt;Window x:Class="WpfTestProject.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:WpfTestProject"
        mc:Ignorable="d"
        Background="WhiteSmoke"
        SizeToContent="WidthAndHeight"
        FocusManager.FocusedElement="{Binding ElementName=FirstValueTextBox}"&gt;
    &lt;Window.DataContext&gt;
        &lt;local:CalculatorViewModel/&gt;
    &lt;/Window.DataContext&gt;

    &lt;Window.InputBindings&gt;
        &lt;KeyBinding Key="A" Modifiers="Control" Command="{Binding AddCommand}"/&gt;
        &lt;KeyBinding Key="S" Modifiers="Control" Command="{Binding SubTractCommand}"/&gt;
        &lt;KeyBinding Key="T" Modifiers="Control" Command="{Binding TimesCommand}"/&gt;
        &lt;KeyBinding Key="D" Modifiers="Control" Command="{Binding DivideCommand}"/&gt;
        &lt;KeyBinding Key="P" Modifiers="Control" Command="{Binding PercentCommand}"/&gt;
    &lt;/Window.InputBindings&gt;
    
    &lt;Window.Resources&gt;
        &lt;Style TargetType="TextBox"&gt;
            &lt;Setter Property="Margin" Value="5"/&gt;
            &lt;Setter Property="HorizontalContentAlignment" Value="Center"/&gt;
            &lt;Setter Property="VerticalContentAlignment" Value="Center"/&gt;
            &lt;Setter Property="BorderBrush" Value="LightGray"/&gt;
        &lt;/Style&gt;
        &lt;Style TargetType="TextBlock"&gt;
            &lt;Setter Property="Margin" Value="5"/&gt;
            &lt;Setter Property="VerticalAlignment" Value="Center"/&gt;
        &lt;/Style&gt;
        &lt;Style TargetType="Label"&gt;
            &lt;Setter Property="Margin" Value="5"/&gt;
            &lt;Setter Property="HorizontalContentAlignment" Value="Center"/&gt;
            &lt;Setter Property="VerticalContentAlignment" Value="Center"/&gt;
            &lt;Setter Property="BorderBrush" Value="LightGray"/&gt;
            &lt;Setter Property="BorderThickness" Value="1"/&gt;
            &lt;Setter Property="Background" Value="White"/&gt;
        &lt;/Style&gt;
        &lt;Style TargetType="Button"&gt;
            &lt;Setter Property="Margin" Value="5"/&gt;
            &lt;Setter Property="Background" Value="{x:Null}"/&gt;
            &lt;Setter Property="BorderBrush" Value="LightGray"/&gt;
            &lt;Setter Property="Height" Value="38"/&gt;
            &lt;Setter Property="Width" Value="{Binding Path=Height, RelativeSource={RelativeSource Self}}"/&gt;
           
        &lt;/Style&gt;
    &lt;/Window.Resources&gt;
    
    &lt;StackPanel&gt;
        &lt;TextBlock Text="Calculator" HorizontalAlignment="Center"
               FontSize="34" Foreground="BlueViolet"/&gt;

        &lt;Grid Margin="5,10,5,5" KeyboardNavigation.TabNavigation="Cycle"&gt;
            &lt;Grid.ColumnDefinitions&gt;
                &lt;ColumnDefinition Width="*"/&gt;
                &lt;ColumnDefinition Width="auto"/&gt;
                &lt;ColumnDefinition Width="*"/&gt;
                &lt;ColumnDefinition Width="auto"/&gt;
                &lt;ColumnDefinition Width="*"/&gt;
            &lt;/Grid.ColumnDefinitions&gt;

            &lt;TextBox x:Name="FirstValueTextBox" Grid.Column="0" Text="{Binding FirstValue}" /&gt;
            &lt;TextBlock Text="{Binding MathMethod}" Grid.Column="1"/&gt;
            &lt;TextBox x:Name="SecondValueTextBox" Grid.Column="2" Text="{Binding SecondValue}"/&gt;
            &lt;TextBlock Text="=" Grid.Column="3" VerticalAlignment="Center" Margin="5"/&gt;
            &lt;Label  Grid.Column="4" Margin="5"
                   Content="{Binding ResultValue, BindsDirectlyToSource=True}"/&gt;
        &lt;/Grid&gt;

        &lt;StackPanel Orientation="Horizontal" Margin="5"&gt;
            &lt;Button Content="+" Command="{Binding AddCommand}"/&gt;
            &lt;Button Content="-" Command="{Binding SubTractCommand}"/&gt;
            &lt;Button Content="*" Command="{Binding TimesCommand}"/&gt;
            &lt;Button Content="/" Command="{Binding DivideCommand}"/&gt;
            &lt;Button Content="%" Command="{Binding PercentCommand}"/&gt;
        &lt;/StackPanel&gt;
        
    &lt;/StackPanel&gt;
&lt;/Window&gt;

</code></pre>
<hr />
<ol start="2">
<li><strong>קודים המהווים בסיס ל-viewmodel</strong></li>
</ol>
<hr />
<pre><code>using System;
using System.Windows.Input;

namespace WpfTestProject
{
    public abstract class ICommandBase : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public virtual bool CanExecute(object parameter)
        {
            return true;
        }

        public abstract void Execute(object parameter);

        protected void OnCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, new EventArgs());
        }
    }

    public class RelayCommand : ICommandBase
    {
        private Action commandTask;

        public RelayCommand(Action action)
        {
            commandTask = action;
        }
        public override void Execute(object parameter)
        {
            commandTask();
        }
    }
}

 public class INotifyPropertyChangedBase : INotifyPropertyChanged
 {
     public event PropertyChangedEventHandler PropertyChanged;
     protected void OnPropertyChanged(string propertyName)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
 }
</code></pre>
<hr />
<ol start="3">
<li><strong>ה-viewmodel</strong></li>
</ol>
<hr />
<pre><code>using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace WpfTestProject
{
    public class CalculatorViewModel : INotifyPropertyChangedBase
    {
        #region members
        string _mathMethod;
        double _firstValue;
        double _secondValue;
        double _result;
        #endregion

        #region properties
        public string MathMethod { get =&gt; _mathMethod; set { _mathMethod = value; OnPropertyChanged(nameof(MathMethod)); } }
        public double FirstValue { get =&gt; _firstValue; set =&gt; _firstValue = value; }
        public double SecondValue { get =&gt; _secondValue; set =&gt; _secondValue = value; }
        public double ResultValue { get =&gt; _result; set { _result = value; OnPropertyChanged(nameof(ResultValue)); } }
        #endregion

        #region Commands
        public ICommand AddCommand
        {
            get
            {
                //return plusCommand;
                return new RelayCommand(Add);
            }
        }
        public ICommand SubTractCommand
        {
            get
            {
                return new RelayCommand(SubTract);
            }
        }
        public ICommand TimesCommand
        {
            get
            {
                return new RelayCommand(Times);
            }
        }
        public ICommand PercentCommand
        {
            get
            {
                return new RelayCommand(Percent);
            }
        }
        public ICommand DivideCommand
        {
            get
            {
                return new RelayCommand(Divide);
            }
        }
        #endregion

        #region Methods
        public void Add()
        {
            MathMethod = "+";
            ResultValue = FirstValue + SecondValue;
            return;
        }
        public void SubTract()
        {
            MathMethod = "-";
            ResultValue = FirstValue - SecondValue;
        }
        public void Times()
        {
            MathMethod = "*";
            ResultValue = FirstValue * SecondValue;
        }
        public void Divide()
        {
            MathMethod = "/";
            ResultValue = FirstValue / SecondValue;
        }
        public void Percent()
        {
            MathMethod = "%";
            ResultValue = FirstValue * SecondValue;
        }
        #endregion
    }
}

</code></pre>
<ol start="4">
<li>שמתם לב? ה-model חסר.... בתוכנה זו לא היה צורך ב-model בעיקרון ה-model היה יכול להיות אחד משני דברים. או class עם מבנה נתונים. או class עם קוד חיצוני.</li>
</ol>
]]></description><link>https://tchumim.com/topic/16342/הדגמה-פשוטה-של-mvvm-ב-c-wpf</link><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 09:34:41 GMT</lastBuildDate><atom:link href="https://tchumim.com/topic/16342.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 02 Jun 2024 22:59:42 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to הדגמה פשוטה של MVVM ב-C# WPF on Sun, 02 Jun 2024 23:16:26 GMT]]></title><description><![CDATA[<p dir="auto"><strong>יש לכם הערות? אנא כתבו אותם לתועלת כולם!</strong></p>
<p dir="auto">הערה: אישית אני ראיתי תועלת גדולה ב-mvvm, למרות שביישום של commands לא כל כך ראיתי תועלת בפרוייקטים שלי כי לרוב זה לא היה נצרך ורק הפך את הקוד למסורבל, בכל אופן הדוגמא דלהלן כוללת אותם לצורך ההדגמה ואפשר לראות כיצד הם 'מחליקים' את פעולת התוכנה, כמו"כ הוספתי קיצורי מקשים דרך ה-commands מה שמדגים את השימושיות שלהם.</p>
]]></description><link>https://tchumim.com/post/162506</link><guid isPermaLink="true">https://tchumim.com/post/162506</guid><dc:creator><![CDATA[pcinfogmach]]></dc:creator><pubDate>Sun, 02 Jun 2024 23:16:26 GMT</pubDate></item></channel></rss>