UserControl not working - xaml

Here is my usercontrol XAML
<UserControl x:Class="UserControlTest.Controls.FullNameControl"
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:local="using:UserControlTest.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="100"
d:DesignWidth="100"
mc:Ignorable="d">
<Grid>
<TextBlock Text="{Binding FirstNameText}" />
</Grid>
</UserControl>
Here is the code behind for the usercontrol
public sealed partial class FullNameControl : UserControl
{
public FullNameControl()
{
this.InitializeComponent();
}
public string FirstNameText
{
get { return (string)GetValue(FirstNameTextProperty); }
set { SetValue(FirstNameTextProperty, value); }
}
public static readonly DependencyProperty FirstNameTextProperty =
DependencyProperty.Register("FirstNameText", typeof(string),
typeof(FullNameControl), new PropertyMetadata(String.Empty));
}
Here is the page that uses the usercontrol
<Page x:Class="UserControlTest.Views.PageWithUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Behaviors="using:Template10.Behaviors"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:controls="using:Template10.Controls"
xmlns:uControls="using:UserControlTest.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:UserControlTest.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:UserControlTest.ViewModels"
mc:Ignorable="d">
<Page.DataContext>
<vm:PageWithUserControlViewModel x:Name="ViewModel" />
</Page.DataContext>
<Grid>
<uControls:FullNameControl FirstNameText="{Binding FirstName, Mode=OneWay}" />
</Grid>
</Page>
Here is the viewmodel that populates the view.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Template10.Common;
using Template10.Mvvm;
using Template10.Services.NavigationService;
using Windows.UI.Xaml.Navigation;
namespace UserControlTest.ViewModels
{
public class PageWithUserControlViewModel : ViewModelBase
{
public PageWithUserControlViewModel()
{
}
private string _FirstName = "Default";
public string FirstName { get { return _FirstName; } set { Set(ref _FirstName, value); } }
public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
{
FirstName = "Terrence";
await Task.CompletedTask;
}
public override async Task OnNavigatedFromAsync(IDictionary<string, object> suspensionState, bool suspending)
{
await Task.CompletedTask;
}
public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
{
args.Cancel = false;
await Task.CompletedTask;
}
}
}

So the missing part was to add this datacontext assignment code to the constructor of the user control after InitializeComponent call
public FullNameControl()
{
this.InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}

Related

Is there a way to create a recursive UWP user control?

I've got a class that has an ObservableCollection of itself embedded within the class.
I'm trying to create a user control that also has a reference to itself in order to display the contents of the observable collection. However, I'm getting a runtime error whenever I'm trying to run the app.
The error is not overly meaningful:
XAML parsing failed.
E_RUNTIME_SETVALUE [Line: 91 Position: 58] (which is the line that has the recursive call to the user control)
The class looks something like this (it's been made shorter for illustration purposes)
public class BookChapterVm : IBookChapterVm
{
public int Id {get;set;}
public string ChapterText {get;set;}
public ObservableCollection<IBookChapterVm> Chapters { get; set; } = new ObservableCollection<IBookChapterVm>();
}
The user control looks something like this (again, unnecessary parts are removed)
<UserControl
x:Class="Cgs.Ux.UserControls.HelpTextEditor.BookChapterEditorCtrl">
<ListView
ItemsSource="{x:Bind Vm.Chapters, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="help:BookChapterVm">
<StackPanel Orientation="Horizontal">
<local:BookChapterEditorCtrl Vm="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>
I've also tried to set up a recursive data template, but it basically ended up with the same error.
Here is a working exemple :
In your page :
<local:RecursiveContainer ViewModel="{Binding}" />
The code behind :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = BuildBookChapterVM();
}
private BookChapterVM BuildBookChapterVM()
{
BookChapterVM vm1 = new BookChapterVM { ChapterText = "1" };
BookChapterVM vm21 = new BookChapterVM { ChapterText = "21" };
BookChapterVM vm22 = new BookChapterVM { ChapterText = "22" };
BookChapterVM vm211 = new BookChapterVM { ChapterText = "211" };
vm1.Chapters.Add(vm21);
vm1.Chapters.Add(vm22);
vm21.Chapters.Add(vm211);
return vm1;
}
}
public class BookChapterVM
{
public int Id { get; set; }
public string ChapterText { get; set; }
public ObservableCollection<BookChapterVM> Chapters { get; set; } = new ObservableCollection<BookChapterVM>();
}
The UserControl XAML :
<UserControl
x:Class="WpfApp2.RecursiveContainer"
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:local="clr-namespace:WpfApp2"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<StackPanel>
<TextBlock Text="{Binding ChapterText}" />
<ItemsControl HorizontalContentAlignment="Stretch" ItemsSource="{Binding Chapters, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RecursiveContainer
Margin="10,5,0,5"
HorizontalAlignment="Stretch"
ViewModel="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</UserControl>
The UC code behind :
public partial class RecursiveContainer : UserControl
{
public RecursiveContainer()
{
InitializeComponent();
}
public BookChapterVM ViewModel
{
get { return (BookChapterVM)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(RecursiveContainer), typeof(RecursiveContainer));
}
See image as proof of concept.
I hope it will help you ;)

Bindable property of custom control not updating - Xamarin Forms

I have created a custom control that contains a label that binds its text to a bindable property.
XAML of custom control:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestProject.CustomControls.MessageBar"
HorizontalOptions="Fill"
VerticalOptions="End"
x:Name="this">
<Frame BackgroundColor="{StaticResource MessageBarColor}"
CornerRadius="0"
Padding="0">
<Label Text="{Binding MessageText, Source={x:Reference this}, Mode=OneWay}"
LineBreakMode="TailTruncation"
MaxLines="3"
FontSize="13"
TextColor="White"
HorizontalOptions="Start"
VerticalOptions="Center"
Margin="20,16"></Label>
</Frame>
</ContentView>
Code behind of custom control:
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TestProject.CustomControls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MessageBar : ContentView
{
public static readonly BindableProperty MessageTextProperty = BindableProperty.Create(
propertyName: nameof(MessageText),
returnType: typeof(string),
declaringType: typeof(MessageBar),
defaultValue: default(string));
public string MessageText
{
get { return (string)GetValue(MessageTextProperty); }
set { SetValue(MessageTextProperty, value); }
}
public MessageBar()
{
InitializeComponent();
}
}
}
Now my problem:
If I use the control in a page and set the MessageText property in XAML, everything works fine. The text is displayed. But when I bind the MessageText property to a ViewModel, no text is displayed. The MessageText property is not set at all.
XAML of page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:customControls="clr-namespace:TestProject.CustomControls"
x:Class="TestProject.MVVM.Pages.ExamplePage">
<StackLayout Orientation="Vertical">
<!-- Works fine -->
<customControls:MessageBar MessageText="This is a message!"></customControls:MessageBar>
<!-- It does not work -->
<customControls:MessageBar MessageText="{Binding Message, Mode=OneWay}"></customControls:MessageBar>
</StackLayout>
</ContentPage>
ViewModel of page:
using Prism.Mvvm;
namespace TestProject.MVVM.ViewModels
{
public class ExampleViewModel : BindableBase
{
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
public ExampleViewModel()
{
Message = "Message from viewModel!";
}
}
}
What am I doing wrong?
P.S.:
I have already found some posts on this topic, but they did not contain any working solutions. Many suggested giving the custom control a name and binding the property with x:Reference. I did this as you can see, but it still doesn't work.
There is nothing wrong with your Custom control, I use a simple model and it works well on my side. Check the BindingContext and message in your ExamplePage.cs.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
ExampleViewModel vm = new ExampleViewModel();
vm.Message = "test";
BindingContext = vm;
}
}
public class ExampleViewModel : INotifyPropertyChanged
{
private string _message;
public event PropertyChangedEventHandler PropertyChanged;
public string Message
{
set
{
if (_message != value)
{
_message = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Message"));
}
}
}
get
{
return _message;
}
}
public ExampleViewModel()
{
Message = "Message from viewModel!";
}
}
I uploaded a sample project here.
Hello, Have you register ViewModel with the view in App.cs file Like
this
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
}

Caliburn Micro Win8.1 App - No target found for method X

I'm a xaml novice and pretty new to WPF/Store apps. I tried to create a simple example of Caliburn Micro (compiled on the recent code) for a Windows 8.1 Store app. But I was unable to get it running as since yesterday I'm getting the error - I did tried the samples under the source I'd downloaded, they just work fine. Same I tried to create from scratch, it throws the aforementioned exception.
Here is the code of the entire solution, please correct me if I've configured/used it wrong!
CalMicSample\App.xaml:
<caliburn:CaliburnApplication
x:Class="CalMicSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:caliburn="using:Caliburn.Micro"
RequestedTheme="Light">
</caliburn:CaliburnApplication>
CalMicSample\App.xaml.cs
using Caliburn.Micro;
using CalMicSample.ViewModels;
using CalMicSample.Views;
using System;
using System.Collections.Generic;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml.Controls;
namespace CalMicSample
{
public sealed partial class App
{
private WinRTContainer container;
private INavigationService navigationService;
public App()
{
InitializeComponent();
}
protected override void Configure()
{
LogManager.GetLog = t => new DebugLog(t);
container = new WinRTContainer();
container.RegisterWinRTServices();
container.RegisterSharingService();
container
.PerRequest<MyTestViewModel>();
PrepareViewFirst();
}
protected override object GetInstance(Type service, string key)
{
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new Exception("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override void PrepareViewFirst(Frame rootFrame)
{
navigationService = container.RegisterNavigationService(rootFrame);
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
Initialize();
var resumed = false;
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
resumed = navigationService.ResumeState();
}
if (!resumed)
DisplayRootView<MyTestView>();
}
}
}
CalMicSample\Helpers\ViewModelHelper.cs
using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace CalMicSample.Helpers
{
public static class ViewModelHelper
{
public static bool Set<TProperty>(
this INotifyPropertyChangedEx This,
ref TProperty backingField,
TProperty newValue,
[CallerMemberName] string propertyName = null)
{
if (This == null)
throw new ArgumentNullException("This");
if (string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException("propertyName");
if (EqualityComparer<TProperty>.Default.Equals(backingField, newValue))
return false;
backingField = newValue;
This.NotifyOfPropertyChange(propertyName);
return true;
}
}
}
CalMicSample\Models\MonkeyMood.cs
namespace CalMicSample.Models
{
public class MonkeyMood
{
public string Message { get; set; }
public string ImagePath { get; set; }
}
}
CalMicSample\ViewModels\MyTestViewModel.cs
using Caliburn.Micro;
using CalMicSample.Helpers;
using CalMicSample.Models;
using System;
namespace CalMicSample.ViewModels
{
public class MyTestViewModel : ViewModelBase
{
private string food;
private MonkeyMood mood;
public MyTestViewModel(INavigationService navigationService)
: base(navigationService)
{
}
public string Food
{
get
{
return food;
}
set
{
this.Set(ref food, value);
}
}
public MonkeyMood Mood
{
get
{
return mood;
}
set
{
this.Set(ref mood, value);
}
}
public void FeedMonkey(string monkeyFood)
{
if (string.Compare(Food, "banana", StringComparison.CurrentCultureIgnoreCase) == 0)
{
Mood = new MonkeyMood();
Mood.Message = "Monkey is happy!";
Mood.ImagePath = #"D:\Tryouts\CaliburnMicroSample\CalMicSample\CalMicSample\Assets\monkey-happy.jpg";
}
else
{
Mood = new MonkeyMood();
Mood.Message = "Monkey is unhappy";
Mood.ImagePath = #"D:\Tryouts\CaliburnMicroSample\CalMicSample\CalMicSample\Assets\monkeysad.jpg";
}
}
public bool CanFeedMonkey(string monkeyFood)
{
return !string.IsNullOrWhiteSpace(monkeyFood);
}
}
}
CalMicSample\ViewModels\ViewModelBase.cs
using Caliburn.Micro;
namespace CalMicSample.ViewModels
{
public abstract class ViewModelBase : Screen
{
private readonly INavigationService navigationService;
protected ViewModelBase(INavigationService navigationService)
{
this.navigationService = navigationService;
}
public void GoBack()
{
navigationService.GoBack();
}
public bool CanGoBack
{
get
{
return navigationService.CanGoBack;
}
}
}
}
CalMicSample\Views\MyTestView.xaml
<Page
x:Class="CalMicSample.Views.MyTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CalMicSample.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:caliburn="using:Caliburn.Micro"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="171*"/>
<RowDefinition Height="86*"/>
<RowDefinition Height="382*"/>
<RowDefinition Height="129*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="172*"/>
<ColumnDefinition Width="328*"/>
<ColumnDefinition Width="183*"/>
</Grid.ColumnDefinitions>
<Button x:Name="FeedMonkey" Content="Feed" caliburn:Message.Attach="FeedMonkey" Grid.Column="2" HorizontalAlignment="Left" Height="72" Margin="7,7,0,0" Grid.Row="1" VerticalAlignment="Top" Width="138" FontSize="36"/>
<TextBox x:Name="txtFood" Grid.Column="1" HorizontalAlignment="Left" Height="66" Margin="10,10,0,0" Grid.Row="1" TextWrapping="Wrap" Text="Banana" VerticalAlignment="Top" Width="636" FontSize="36"/>
<TextBlock x:Name="lblFeedMonkey" Grid.Column="1" HorizontalAlignment="Left" Margin="10,119,0,5" TextWrapping="Wrap" Text="Give some food to the monkey" Width="636" FontSize="36" FontWeight="Bold"/>
<TextBlock x:Name="lblMonkeyMood" Grid.Column="1" HorizontalAlignment="Center" Margin="59,25,37,10" Grid.Row="3" TextWrapping="Wrap" VerticalAlignment="Center" Height="94" Width="560" FontSize="72"/>
<Image x:Name="imgMonkey" Grid.Column="1" HorizontalAlignment="Left" Height="362" Margin="10,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="636"/>
</Grid>
</Page>
CalMicSample\Views\MyTestView.xaml.cs
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace CalMicSample.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MyTestView : Page
{
public MyTestView()
{
this.InitializeComponent();
}
}
}
Your feedmonkey method in your vm wants a string parameter, but your not supplying one when attaching to your button. See here for more info: http://caliburnmicro.codeplex.com/wikipage?title=Cheat%20Sheet
Rob is correct, you need to match the method signature of your FeedMonkey(string monkeyFood), at the moment so `Caliburn.Micro' is unable to locate the correct method.
You'd want to use something like:
// You wouldn't want to use a hard coded string, but this is how you'd do it.
caliburn:Message.Attach="FeedMonkey('banana')"
// Or you can pass some of the special values linked in Rob's answer (the Caliburn docs).
// You'd probably want a sub property, depending on what it was you were passing.
caliburn:Message.Attach="FeedMonkey($dataContext)"

Win8 XAML How to bind a List<> to a ListView

I'm trying to populate a list view control on a XAML page in a Win8 application. I've added the following attributes to the page XAML:
<common:LayoutAwarePage x:Class="SecAviTools.ViewWeatherHome"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:MyNameSpace.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:MyNameSpace"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodel="using:MyNameSpace.Win8ViewModel"
x:Name="pageRoot"
DataContext="{Binding DefaultViewModel,
RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
<!-- ... -->
<ListView ItemsSource="{Binding Path=viewmodel:Stations}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Id}"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My source class is:
namespace MyNameSpace.Win8ViewModel
{
public class Stations : INotifyPropertyChanged, INotifyCollectionChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected void OnCollectionChanged<T>(NotifyCollectionChangedAction action, ObservableCollection<T> items)
{
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, items));
}
public Stations()
{
AllStations = new ObservableCollection<Station>();
AddStations(new List<Station>());
}
public ObservableCollection<Station> AllStations { get; private set; }
public void AddStations(List<Station> stations)
{
AllStations.Clear();
foreach (var station in stations)
AllStations.Add(station);
OnCollectionChanged(NotifyCollectionChangedAction.Reset, AllStations);
OnPropertyChanged("AllStations");
}
}
public class Station
{
public int Id { get; set; }
public string Name { get; set; }
}
}
There is also a button on the page (not shown here) that does the following:
public sealed partial class MyPage : MyNameSpace.Common.LayoutAwarePage
{
private Stations m_Stations = new Stations();
//...
private async void SearchButtonClick(object sender, RoutedEventArgs e)
{
var list = new List<Station>();
list.Add(new Station() { Id = 0, Name = "Zero" });
list.Add(new Station() { Id = 1, Name = "One" });
m_Stations.AddStations(list);
}
}
However, when I run the code, nothing appears in the list view. What am I missing?
TIA
You don't show what DefaultViewModel is, but I'll assume it's set to be an instance of the class you show, Stations. In that case, you need to binding to be:
<ListView ItemsSource="{Binding Path=AllStations}">
The Path of a binding usually refers to a property somewhere; with no further specification, such as a Source, it's a property on the object that is set to be the DataContext.
Regardless, you don't need the namespace qualifier "viewmodel:".
As an aside, if you do end up binding to the ObservableCollection, you don't need to implement INotifyCollectionChanged, only INotifyPropertyChanged for when the AllStations property is set.

Passing a dictionary to a behavior

I have a simple Behavior like that
public class KeyBoardChangeBehavior : Behavior<UserControl>
{
public Dictionary<string, int> DataToCheckAgainst;
protected override void OnAttached()
{
AssociatedObject.KeyDown += _KeyBoardBehaviorKeyDown;
}
protected override void OnDetaching()
{
AssociatedObject.KeyDown -= _KeyBoardBehaviorKeyDown;
}
void _KeyBoardBehaviorKeyDown(object sender, KeyEventArgs e)
{
// My business will go there
}
}
I want to asign value to this dictionary from the view , I call it as following
<UserControl x:Class="newhope2.MainPage"
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:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Behaviors="clr-namespace:newhope2"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Interactivity:Interaction.Behaviors>
<Behaviors:KeyBoardChangeBehavior />
</Interactivity:Interaction.Behaviors>
<Grid x:Name="LayoutRoot" Background="White">
</Grid>
</UserControl>
but how can I pass this dictionary to the behavior from XAML or its code behind
To take a Binding, a property needs to be a DependencyProperty.
You need to define the property, in the Behaviour, like so:
public Dictionary<string, int> DataToCheckAgainst
{
get { return (Dictionary<string, int>)GetValue(DataToCheckAgainstProperty); }
set { SetValue(DataToCheckAgainstProperty, value); }
}
public static readonly DependencyProperty DataToCheckAgainstProperty =
DependencyProperty.Register(
"DataToCheckAgainst",
typeof(Dictionary<string, int>),
typeof(KeyBoardChangeBehavior),
new PropertyMetadata(null));
Use the Visual Studio "propdp" snippet.
Usage is as Adi said, like so:
<Interactivity:Interaction.Behaviors>
<Behaviors:KeyBoardChangeBehavior DataToCheckAgainst="{Binding MyDictionary}" />
</Interactivity:Interaction.Behaviors>
All you need to do is declare the dictionary as a property and then pass it a value via binding.
In the behavior:
public Dictionary<string, int> DataToCheckAgainst { get; set; }
In XAML:
<Interactivity:Interaction.Behaviors>
<Behaviors:KeyBoardChangeBehavior DataToCheckAgainst="{Binding MyDictionary}" />
</Interactivity:Interaction.Behaviors>