How should the ViewModel refer to its Models properties? - c#

As the ViewModel has the job to "prepare" the Model's properties to get displayed in the View, what is the best way of referring to the underlying Models properties from the ViewModel?
I could think about two solutions by now:
Option 1 - Duplicate the Model's properties in the ViewModel (wrapper-approach)
Architecture
class Model
{
public string p1 { get; set; }
public int p2 { get; set; }
}
class ViewModel : INotifyPropertyChanged
{
// Model-instance for this ViewModel
private Model M;
public string p1
{
get { return M.p1; }
set
{
M.p1 = value;
// assuming View controls are bound to the ViewModel's properties
RaisePropertyChanged("p1");
}
}
// let's say, I only want to check a Checkbox in the View,
// if the value of p2 exceeds 10.
// Raising the property changed notification would get handled
// in the modifying code instead of the missing setter of this property.
public bool p2
{
get
{
if (M.p2 > 10)
{ return true; }
else
{ return false; }
}
}
// Initialize the Model of the ViewModel instance in its c'tor
public ViewModel()
{ M = new Model(); }
}
Binding
<Textbox Text="{Binding p1}"/>
<Checkbox IsEnabled="False" IsChecked="{Binding p2, Mode=OneWay}"/>
Advantages
Full control about how the Model's properties are displayed on the View as shown in p2: int gets converted to bool on demand.
Changes of the properties of the ViewModel could be raised individual, might be a little performance increase compared to option 2.
Disadvantages
Violation of DRY.
More Code to write/maintain.
Modifications to the Model/ViewModel could easily become shotgun surgery.
Option 2 - Treat the whole Model as property of the ViewModel
Architecture
class Model
{
public string p1 { get; set; }
public int p2 { get; set; }
}
class ViewModel : INotifyPropertyChanged
{
// Model instance for this ViewModel (private field with public property)
private Model _M;
public Model M
{
get { return _M; }
set
{
_M = value;
// Raising the changing notification for the WHOLE Model-instance.
// This should cause ALL bound View-controls to update their values,
// even if only a single property actually got changed
RaisePropertyChanged("M");
}
}
// Initialize the Model of the ViewModel instance in its ctor
public ViewModel()
{ M = new Model(); }
}
Binding
<Textbox Text="{Binding M.p1}"/>
<Checkbox IsEnabled="False" IsChecked="{Binding M.p2, Mode=OneWay, Converter={StaticResource InverseBooleanConverter}"/>
Advantages
Can save a lot of code.
Reduces complexity.
Increases maintainability.
Disadvantages
In this approach, the ViewModel is nothing more than a continuous-flow water heater for the Models properties, except for some possible interaction logic for the View.
No control about how the Model's properties are displayed in the View - which ultimately leads to total needlessness of the ViewModel and implementation of conversion logic in the View.

It is the responsibility of your ViewModel to expose the Model to the View, you should not expose the Model's properties as additional properties in the ViewModel, instead, your View should bind directly to the model.
Additionally, it isn't wrong to have logic in your Model, in fact, it makes more sense to contain model related code within the model, as opposed to the ViewModel.
Here is an example:
public class Movie
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
//Notify property changed stuff (if required)
//This is obviously a stupid example, but the idea
//is to contain model related logic inside the model.
//It makes more sense inside the model.
MyFavourite = value == "My Movie";
}
}
private bool _MyFavourite;
public bool MyFavourite
{
get { return _MyFavourite; }
set
{
_MyFavourite = value;
//Notify property changed stuff.
}
}
}
So to answer your question a little more directly, you should expose your model in the view model as a property.
public class ViewModel
{
private Movie _Model;
public Movie Model
{
get { return _Model; }
set
{
_Model = value;
//Property changed stuff (if required)
}
}
...
}
Therefore, your View will bind to the Model property, like you have already done so.
EDIT
In the example for casting to the type, you can implement a read-only property in your Model, like so:
public bool MyBool
{
get
{
return MyInt > 10; }
}
}
Now the magic here would be that you will need to call the INotifyPropertyChanged for this property whenever MyInt changes. So your other property would look something like this:
public int MyInt
{
get { ... }
set
{
_MyInt = value;
//Notify property changed for the read-only property too.
OnPropertyChanged();
OnPropertyChanged("MyBool");
}
}

In my view, Model should not have RaisePropertyChanged stuff. Some view models (e.g. Blazor) might not need it, others (e.g. WPF) might use other mechanisms like DependencyProperty. Thus, to me Model is a POCO class. Hence, it becomes ViewModel responsibility to report changes to the data up to the View. Consequently, ViewModel is bound to wrap Model's properties (OA's option 1).
You might want to look at AutoMapper to centralize the mappings.

Related

How to provide and pass "object" to the viewmodelbase?

I just started to do MVVM because a have heard a lot of its benefits about:
Clean code
Reusable code
Better code organized
So started to do a usual "Code behind" to make sure that my code is working, and then apply MVVM to clean it up.
so here is one of my "code behind" example:
private const int LED_PIN = 17, RELAY_PIN = 27;
private GpioPin LEDpin, RELAYpin;
private bool InitGPIO(TextBlock txt)
{
var gpio = GpioController.GetDefault();
// Show an error if there is no GPIO controller
if (gpio == null)
{
txt.Text = "There is no GPIO controller on this device.";
txt.Foreground = new SolidColorBrush(Colors.Red);
return false;
}
txt.Text = "GPIO controller initialized correctly.";
txt.Foreground = new SolidColorBrush(Colors.Green);
LEDpin = gpio.OpenPin(LED_PIN);
RELAYpin = gpio.OpenPin(RELAY_PIN);
LEDpinValue = GpioPinValue.Low;
RELAYpinValue = GpioPinValue.High;
LEDpin.Write(LEDpinValue);
RELAYpin.Write(RELAYpinValue);
LEDpin.SetDriveMode(GpioPinDriveMode.Output);
RELAYpin.SetDriveMode(GpioPinDriveMode.Output);
return true;
}
To use this "InitGPIO" method I have to provide:
fixed "int" pin.
GpioPin types.
GpioPinValue type.
A textblock to display what is wrong.
I already create a ViewModelBase and the simplify method to get it read:
public class ViewModelBase
{
public InitGpioCommand InitGpiocommand { get; set; }
public ViewModelBase()
{
this.InitGpiocommand = new InitGpioCommand(this);
}
public bool InitGPIO(DigitalControl dc)
{
var gpio = GpioController.GetDefault();
// Show an error if there is no GPIO controller
if (gpio == null)
{
dc.Status.Text = "There is no GPIO controller on this device.";
dc.Status.Foreground = new SolidColorBrush(Colors.Red);
return false;
}
dc.Status.Text = "GPIO controller initialized correctly.";
dc.Status.Foreground = new SolidColorBrush(Colors.Green);
dc.DevicePin = gpio.OpenPin(dc.PinNumber);
dc.PinValue = GpioPinValue.Low;
dc.DevicePin.Write(dc.PinValue);
dc.DevicePin.SetDriveMode(GpioPinDriveMode.Output);
return true;
}
}
everything had been wrap up in this Model:
public class DigitalControl
{
public TextBlock Status { get; set; }
public GpioPin DevicePin { get; set; }
public GpioPinValue PinValue { get; set; }
public int PinNumber { get; set; }
}
and my current button to fire the InitGPIO method:
<Button x:Name="FirstLightTest"
Content="Test"
Command="{Binding InitGPIO,Source={StaticResource viewmodel}}">
</Button>
Of course this will not work.
I realize I have to:
Pass a "TextBlock" from xaml to the method parameter in ViewModelBase.
Assign GpioPin, GpioPinValue and PinNumber somewhere in C# code and also pass them to the Method inside the ViewModelBase.
In order to fill up all the parameters in that method.
I don't really know this is a bad MVVM design or not but I think the best to use this complicated pattern is to break it down smaller problems like this and see if how valuable it is.
There are some mix-ups in the code. First of all, the Binding is bound to InitGIPO, which is a method. This will not work as Command can be bound to a ICommand property only. In this case, the proper target would be the InitGpiocommand. I always recommend using an existing MVVM framework as a starting point, for example the MVVM Light framework or MvvmCross. Those provide the implementation of a simple DelegateCommand which can just call a simple parameterless method. You could then have the method look like this:
private bool InitGPIO()
{
...
}
Now, where do we get the DigitalControl instance? We will add a property to our view model that will represent this instance:
public DigitalControl DigitalControl { get; } = new DigitalControl();
As #max already mentioned, it definitely discouraged to put UI controls into any View Model properties, so let's change the definition of DigitalControl to this:
public class DigitalControl
{
public string Status { get; set; }
public GpioPin DevicePin { get; set; }
public GpioPinValue PinValue { get; set; }
public int PinNumber { get; set; }
}
The Status property can now be data-bound to the TextBlock, like this:
<TextBlock Text="{Binding DigitalControl.Status, Mode=TwoWay}" .../>
Once the user modifies the TextBlock, the change will automatically propagate to the view model's DigitalControl instance's Status property.
To reference the DigitalControl property in InitGIPO you can just reference it as any other property within the view model.
To me having a UI component (TextBlock) inside a model is a violation of MVVM-pattern. Instead the TextBlock's properties should be bound to the view-model via binding mechanism and not assigned directly.
To sum up:
Remove the TextBlock reference from the model
Provide properties in the view-model that TextBlock can be bound to (text, foreground color or a boolean flag).
Bind to the view-model properties from xaml.

Make updating a property in one class trigger the setter for a property of that type in another class

I am using MVVM with Galasoft MVVMLight libraries.
I have two models; each has a boolean property and different properties of the same type.
public class Model1 : ObservableObject
{
public EnumPair<YesNoInherit> Model1Property
{
get { return _model1Property; }
set
{
_model1Property = value;
Updated = true
RaisePropertyChanged("Model1Property");
}
}
public bool Updated
{
get { return _updated; }
set
{
_updated = value;
RaisePropertyChanged("Updated");
}
}
}
public class Model2 : ObservableObject
{
public EnumPair<YesNoInherit> Model2Property
{
get { return _model2Property; }
set
{
_model2Property = value;
Updated = true
RaisePropertyChanged("Model2Property");
}
}
public bool Updated
{
get { return _updated; }
set
{
_updated = value;
RaisePropertyChanged("Updated");
}
}
}
The type YesNoInherit is an enum having values No, Yes, and Inherit.
Here is the EnumPair class.
public class EnumPair<T> : ObservableObject where T : struct, IConvertible
{
public T EnumValue
{
get { return _enumValue; }
set
{
if (Type.Equals(value, _enumValue) == false)
{
_enumValue = value;
RaisePropertyChanged();
}
}
}
public string SourceName
{
get { return _sourceName; }
set
{
_sourceName = value;
RaisePropertyChanged();
}
}
}
In my view, I am trying to use a ComboBox to let the user select one of the three enum values, and, in some cases, display custom text. The resource "enumComboBoxTemplate" allows the ComboBox drop-down to show enum descriptions. The converter "inheritanceEnum2Desc" is where the custom text would be applied. "object1" is an instance of "Model1".
<ComboBox ItemTemplate=ItemTemplate="{StaticResource enumComboBoxTemplate}"
EnumSource="enums:YesNoInherit">
<ComboBox.Text>
<MultiBinding Converter="{StaticResource inheritanceEnum2Desc}">
<Binding Path="object1.EnumValue"/>
<Binding Path="object1.SourceName"/>
</MultiBinding>
</ComboBox.Text>
</ComboBox>
"Model2" would be used in future programming employing similar functionality, but with different data.
When I change the selection in the ComboBox, I want to change the value of "Updated" (from false to true) so I can enable a button in the view. This appears to require that the EnumPair class somehow make the program execute the setter for Model1Property. Since the two model classes have properties of type EnumPair, I don't believe I can add any code in EnumPair specific to either model class.
How can I accomplish this? I would greatly appreciate any assistance.
Basically, you have two options: either use some kind of message-bus to update the other model (Prism has EventAggregator, not sure about MVVMLight) or make both model instances forward their properties to a common data source that notifies all of its users when a property changes.
If you want to be able to easily change from one class to another in the future without rewriting all of your code, you need to create an Interface that defines all of the things that the two models have in common, and both model classes need to implement the interface. You could call the interface IModel1
So, instead of having a "Model1" in your viewmodel, you would have an "IModel1" in your viewmodel instead. You could pass in the same object you are passing in now, which is of type Model1, because it implements the IModel1 interface. When you are ready to switch, pass in a Model2 instead, and it will work without having to rewrite anything in your view or viewmodel. Your setters can be completely different - as long as both models have all of the methods and properties that are required by the interface, you will be OK.
Alternately, if Model2 is exactly like Model1 except that it has "extra stuff," you can make Model2 a derived class which derives from Model1.
Google searching either of those terms should point you toward a good tutorial.

Binding with custom object in MVVM textbox

I have started learning MVVM with some basic applications and I just encountered below issue with binding.
I have 2 textboxes in my View say- Student_name and Student_year. I have a Student class implemented in my viewmodel with its properties. But, the actual Student class is in my Model layer.
<TextBox x:Name="StuName"
Text="{Binding Path=MyStudent.Name, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="StuYear"
Text="{Binding Path=MyStudent.Year, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
ViewModel:
private Student _myStudent = new Student();
public Student MyStudent
{
get { return _myStudent ; }
set
{
if (value != _myStudent )
{
_myStudent = value;
OnPropertyChanged("MyStudent");
}
}
}
Model (Student Class):
public string Name
{
get { return _name; }
set
{
if (_name!= value)
{
_name= value;
OnPropertyChanged("Name");
}
}
}
I can see everything working fine on binding the values from VM to View. But, the other way is behaving little tricky here..
Wheneven I change Name/Year in the textbox, the control has to land on Viewmodel's Set property? Rather, it straight away goes to Model's Set property.
For Instance, When I modify txtbox 'StuName', SET method of Student class is invoked. But not SET method of Viewmodel(MyStudent object).
I am not sure why this behaves in such a way. Is it because I have directly bounded Student.Name to the textbox? What are the alternatives to handle this SET operation in Viewmodel class..
Thanks in advance.
PS: I have implemented INotifyPropertyChanged interface properly and rest other bindings(of primitive data type) are working fine with other controls.
As Philip Stuyck correctly pointed out in his answer, the ViewModel only has a setter for the Student instance, which never changes. So the setter on the ViewModel is never invoked. The binding goes to the name property of that instance.
A different approach would be to wrap the name property in you ViewModel explicitly. This allows for a clearer separation of concerns between Model and ViewModel. I.e. right now your Model implements INotifyPropertyChanged which IMO belongs into the ViewModel, because in general it is only used for triggering View updates. Your ViewModel would look like this:
class StudentViewModel
{
private Student _myStudent = new Student();
public string Name
{
get { return _myStudent.Name ; }
set
{
if (value != _myStudent.Name )
{
_myStudent.Name = value;
OnPropertyChanged("Name");
}
}
}
}
Your Model on the other hand becomes simpler, because it doesn't have to implement INotifyPropertyChanged anymore.
That is normal behavior because your binding is to MyStudent.Name.
So the Mystudent setter is never called because the instance never changes.
The setter of the name is called because in fact that is where your binding is going to.

ViewModel with IDataErrorInfo always calls getter after setting property?

I want to give this question as much context as possible, but, in summary, I'm basically asking two questions:
Does WPF always call the getter after setting a bound property when the setter doesn't throw an exception?
Is it possible to prevent the getter of a bound property from being called after an error has occurred in the setter when the ViewModel implements IDataErrorInfo?
I currently have a Model class that implements validation by throwing an exception from the property setter. Additionally, many of the properties are coupled, so modifying the value of one of them may cause several others to be recalculated. It implements INotifyPropertyChanged to alert outside listeners whenever a recalculation has occurred. It looks something like this:
public class Model : INotifyPropertyChanged
{
private double property1;
public double Property1
{
get { return property1; }
set
{
if (value < 0.0)
throw new Exception("Property1 cannot be less than 0.0.");
property1 = value;
OnPropertyChanged(new PropertyChangedEventArgs("Property1"));
}
}
// ...Everything needed to support INotifyPropertyChanged...
}
Initially, I implemented the ViewModel for this class to act as a thin wrapper around the model properties, providing additional view-specific behaviors whenever an error occurs (flagging invalid data, disabling buttons, etc.):
public class ViewModel : INotifyPropertyChanged
{
private readonly Model model;
public ViewModel()
{
model = new Model();
model.PropertyChanged += (sender, args) => OnPropertyChanged(args);
}
public string Property1
{
get { return model.Property1.ToString(); }
set
{
try
{
model.Property1 = Double.Parse(value);
}
catch (Exception)
{
// Perform any view-specific actions
throw;
}
}
}
// ...Everything needed to support INotifyPropertyChanged
}
Notably, the ViewModel doesn't have any additional backing fields; all of its properties are directly linked to the corresponding properties in the Model, and any PropertyChanged notifications from the Model are passed along by the ViewModel.
But, I've frequently heard that using exceptions for validation can be limiting, and I'm starting to realize the same, specifically as the need for cross-coupled validation rules has increased in this application.
I didn't want to change behaviors of the Model, since it is already being used in several other places, but I went about changing the ViewModel to implement IDataErrorInfo:
public class ViewModel : INotifyPropertyChanged, IDataErrorInfo
{
private readonly Model model;
public ViewModel()
{
model = new Model();
model.PropertyChanged += (sender, args) =>
{
errorList.Remove(args.PropertyName);
OnPropertyChanged(args);
};
}
public string Property1
{
get { return model.Property1.ToString(); }
set
{
try
{
model.Property1 = Double.Parse(value);
}
catch(Exception ex)
{
// Perform any view-specific actions
errorList["Property1"] = ex.Message;
}
}
}
private readonly Dictionary<string, string> errorList = new Dictionary<string, string>();
public string this[string propertyName]
{
get
{
string errorMessage;
if (errorList.TryGetValue(propertyName, out errorMessage))
return errorMessage;
return String.Empty;
}
}
public string Error { get { return String.Empty; } }
// ...Everything needed to support INotifyPropertyChanged
}
However, this caused a drastic unwanted change in behavior. When using exceptions, after the user entered an invalid value, the Validation.ErrorTemplate for the control is displayed and the invalid value remains in the control, thus giving the user the opportunity to correct their mistake. When using IDataErrorInfo, WPF seems to call the property getter after the setter has completed. Since the Model hasn't changed whenever an error occurs, the invalid value is replaced by the previous value. So now I have a control displaying the Validation.ErrorTemplate but with a VALID being value displayed!
It seems crazy to me that WPF would automatically call a property getter without receiving a PropertyChanged notification (after the window has been initialized). And it doesn't attempt to call the getter after an exception is thrown, so why would it do it when IDataErrorInfo is used?
Am I doing something wrong that's causing this behavior? Is there a way to prevent WPF from calling the property getter in the ViewModel after an error has occurred in the setter when the ViewModel implements IDataErrorInfo?
I've tried adding backing fields to the ViewModel to store the invalid value, but due to the fact Model properties can be modified outside of the ViewModel (that's the reason it implements INotifyPropertyChanged in the first place), the solution ends up being quite complex and basically unsustainable in an environment with programmers of varying skill levels.
Here's the approach you want to have for form validation in MVVM
Your model
public class Product:IDataErrorInfo
{
public string ProductName {get;set;}
public string this[string propertyName]
{
get
{
string validationResult = null;
switch (propertyName)
{
case "ProductName":
validationResult = ValidateName();
}
}
}
}
Then in your ViewModel
public string ProductName
{
get { return currentProduct.ProductName; }
set
{
if (currentProduct.ProductName != value)
{
currentProduct.ProductName = value;
base.OnPropertyChanged("ProductName");
}
}
}
As another consideration, when I want to validate numbers (such as your double validation), keep the model as having a double instead of a string
public double? Property1 {get;set;}
then you can do this
<Textbox Name="myDoubleTextbox" >
<Binding ValidatesOnDataErrors="true" Path="Property1" TargetValueNull="" />
/>
so when they type something incorrect into the double box, it sends null to your model and you can check against that.
Although it doesn't answer the questions I asked, my coworker suggested that the desired behavior could be achieved by adding the invalid value to the errorList and modifying the getter in the ViewModel to return the invalid value whenever there is an error.
So the properties in the ViewModel look like this:
public string Property1
{
get
{
ErrorInfo error;
if (errorList.TryGetValue("Property1", out error))
return error.Value;
return model.Property1.ToString();
}
set
{
try
{
model.Property1 = Double.Parse(value);
}
catch (Exception ex)
{
// Perform any view-specific actions
errorList["Property1"] = new ErrorInfo(value, ex.Message);
}
}
}
With the following updates to the IDataErrorInfo methods:
private struct ErrorInfo
{
public readonly string Value;
public readonly string Message;
public ErrorInfo(string value, string message)
{
Value = value;
Message = message;
}
}
private readonly Dictionary<string, ErrorInfo> errorList = new Dictionary<string, ErrorInfo>();
public string this[string propertyName]
{
get
{
ErrorInfo error;
if (errorList.TryGetValue(propertyName, out error))
return error.Message;
return String.Empty;
}
}
public string Error { get { return String.Empty; } }
This allows the PropertyChanged event handler to stay the same, and only requires small changes to the property getters and setters.

Displaying data differntly across viewmodels, without changing model data

Another problem has been bugging me lately, and I am quite sure it is my lacking WPF/MVVM skills that prevents me from seing the obvious. I am sure the solution is a simple one, however, I am unsure how to implement it.
I am developing in WPF/C# and I am using the MVVM designpattern.
For simplicity, I am boiling the question down to it's most basic components.
The scenario:
I have a Model, only containing an integer.
I have a Parent ViewModel, displaying this integer.
I have two child viewmodels, incorparated in the parent viewmodel, both displaying this integer. On one of the viewmodel, I have a Command, incrementing the value of the integer with 1. The value is changed in the model, which implements the INotifyPropertyChanged therefore making the second ViewModel aware of the change, so it can update accordingly.
So far everything works fine.
However, I am interested in a new feature, and I cannot get it to work. Say, that I on my second viewmodel want to display the integer, but I want to transform the way the data is displayed. This should be done, however, without changing the data in the model. Should the data in the model change, the transformed data will change accordingly.
As an example, lets assume that the integer is 5. On the second viewmodel, I want to display the integer + 2, meaning 7.
Then the data is changed to 6 from the first viewmodel, meaning that the property on the second viewmodel changes to 8 automatically.
How is this implemented?
A few codepieces, to illustrate what the system looks like so far:
The Model:
public DataModel()
{
data = new Data();
data.Value = 2;
}
public Data data { get; set; }
And the data Class:
public class Data : INotifyPropertyChanged
{
private int m_Value;
public int Value
{
get { return m_Value; }
set
{
if (m_Value != value)
{
m_Value = value;
OnPropertyChanged("Value");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
The mainviewmodel
public class MainViewModel : ViewModelBase
{
readonly DataModel _dataModel;
public MainViewModel()
{
_dataModel = new DataModel();
ViewModel1 = new 1ViewModel(this);
ViewModel2 = new 2ViewModel(this);
}
public 1ViewModel ViewModel1 { get; set; }
public 2ViewModel ViewModel2 { get; set; }
public Data Data
{
get { return _dataModel.data; }
}
}
And here is the way the ChildViewmodels binds themselves to the Data object
public class 1ViewModel : ViewModelBase
{
private MainViewModel _mainViewModel;
public 1ViewModel(MainViewModel mainViewModel)
{
_mainViewModel = mainViewModel;
}
public Data Number
{
get { return _mainViewModel.data; }
}
}
And on the view1, i have bound the Number property like this
<TextBlock Text="{Binding Path=Number.Value}" />
Again, I want to be able to create a second property on the viewmodel, which displays the transformed data, based on, but without changing the original data, and which updates together with the data being updated.
Preferably, it should be a kind of converter-method, which converts the data to the new data.
Hope you are able to help.
The ViewModel should hold the data ready for display but not knowledgeable on the way in which it will be displayed. If you want to change the way in which the data is displayed in your View, for that you would use a Converter. This would allow you to use the same ViewModel for multiple Views and have different appearances.
In addition wrapping a ViewModel inside a ViewModel is not necessarily the way you want to go. A ViewModel generally has an associated View. If you have no view for the ViewModel, treat the data as typical classes and proceed with your single ViewModel.
Use an IValueConverter:
public class AddConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value + (int)parameter;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value - (int)parameter;
}
}
And in your XAML, add the resource:
And update your binding:
I used a ConverterParameter here, but you can hardcode the value if so desired. Might want to add some checks to your converter as well, as it will throw an exception if the types are not correct.

Categories