user2429022
user2429022

Reputation: 15

Looking for a way to update a non-dependency property in MVVM application

I am writing terimnal application in WPF. I receive characters from an embedded device and I update a TextBox.Text property that is bounded to my ViewModel.

The problem is that the TextBox Caret is reset when I update the text property. what I would like to do is hold a Caret parameter in my viewModel and bind it to the Caret property of the TextBox, however the TextBox Caret is not a dependency property and I don't want to access the view directly from my view model.

Are you familiar with a proper solutionthat does not break the MVVM pattern?

Thanks in advance.

Upvotes: 0

Views: 128

Answers (1)

Ayyappan Subramanian
Ayyappan Subramanian

Reputation: 5366

You can add attached property to bind non-dependency property. below example i have created it for CaretIndex property of the textbox.

<Window x:Class="Converter_Learning.Window7"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:Converter_Learning"
    Title="Window7" Height="500" Width="500">
<Grid FocusManager.FocusedElement="{Binding ElementName=txt}">
    <TextBox x:Name="txt" Text="Hiiiiiiiiiiiiiii" local:TextBoxHelper.Caret="{Binding Caret}" />
</Grid>

public partial class Window7 : Window
{
    public Window7()
    {
        InitializeComponent();            
        this.DataContext= new CaretViewModel();
    }
}

public class CaretViewModel : INotifyPropertyChanged
{
    private int myVar;

    public int Caret
    {
        get { return myVar; }
        set { myVar = value; Notify("Caret"); }
    }

    public CaretViewModel()
    {
        Caret = 5;
    }
    public event PropertyChangedEventHandler PropertyChanged;

    void Notify(string property)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

public static class TextBoxHelper
{

    public static int GetCaret(DependencyObject obj)
    {
        return (int)obj.GetValue(CaretProperty);
    }

    public static void SetCaret(DependencyObject obj, int value)
    {
        obj.SetValue(CaretProperty, value);
    }

    public static readonly DependencyProperty CaretProperty =
        DependencyProperty.RegisterAttached(
            "Caret",
            typeof(int),
            typeof(TextBoxHelper),
            new FrameworkPropertyMetadata(0, CaretChanged));

    private static void CaretChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        TextBox tb = obj as TextBox;
        if (tb != null)
        {
            int newValue = (int)e.NewValue;

            if (newValue != tb.CaretIndex)
            {                    
                tb.CaretIndex = (int)newValue;
            }
        }
    }

}

Upvotes: 1

Related Questions