wpf fire PropertyChanged event in binding source that binding gets updated - c#

I'm trying to make some CustomControl Textboxes with validation features.
(for example a number only textbox or a zip-code textbox etc.)
It should realized in a .dll library file.
My project contains a CustomControl for the textbox, a class wich handles the validations,
and a ErrMsgGui CustomControl that should show a error message in a TextBlock
(exmp.: Only numbers allowed...)
My problem is that I don't get the TextBlock Text updated when a method in the validation class is called
Is there a way to trigger the PropertyChangeEvent which updates the Textblock text within the validaiton class?
(Im quite new to wpf)
Generic.xaml:
<Style TargetType="{x:Type local:NumTb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NumTb}">
<TextBox Background="{TemplateBinding Background}" Text="{Binding Source={StaticResource NumTbVm}, Path=NumTbText, UpdateSourceTrigger=PropertyChanged}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ErrMsgGui}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ErrMsgGui}">
<TextBlock Text="{ Binding Source={StaticResource val}, Path=ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Validations.cs:
private const string ONLY_NUMBERS_REGEX = #"^[0-9]+$"; //Nur Zahlen
private string _ErrMsgGuiText;
public string ErrMsgGuiText
{
get { return _ErrMsgGuiText; }
set
{
_ErrMsgGuiText = value;
Debug.Print("QueryText: " + value);
OnPropertyChanged("ErrMsgGuiText");
}
}
public object[] onlyNumbers(string s2c, bool output)
{
object[] objRes = new object[2];
bool result = true;
string errMsg = "";
Regex regex = new Regex(ONLY_NUMBERS_REGEX);
if (s2c != null && s2c != "" && !regex.IsMatch(s2c))
{
result = false;
errMsg = "Nur Zahlen sind zulässig";
}
objRes[0] = result;
objRes[1] = errMsg;
if (output == true)
{
ErrMsgGuiText = errMsg;
}
return objRes;
}
public void onlyNumbers(string s2c)
{
onlyNumbers(s2c, true);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
NumTbViewModel.cs:
Validations val = null;
public NumTbViewModel()
{
val = new Validations();
}
private string _NumTbText;
public string NumTbText
{
get { return _NumTbText; }
set
{
_NumTbText = value;
this.OnPropertyChanged("NumTbText");
val.onlyNumbers(_NumTbText);
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}

It looks like the TextBlock source is looking at a static resource for the Validations class and the Validations called in your NumTbViewModel is NOT the same as the static resource. A solution could be to add a property to NumTbViewModel.cs and point your binding to that property so the Validations class instances will be the same. In NumTbViewModel.cs add:
Validations _val;
public Validations Val
{
get { return _val; }
set
{
_val = value;
this.OnPropertyChanged("Val");
}
}
Change your source and path in xaml binding on the TextBlock:
<TextBlock Text="{ Binding Source={StaticResource NumTbVm}, Path=Val.ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
Another way:
You could also set the Val property of your NumTbViewModel when you define your static resource like so:
<local:Validations x:Key="val" />
<local:NumTbViewModel x:Key="NumTbVm" Val="{StaticResource val}" />
Doing this you can keep the bindings like you originally had.

Related

Unable to set Custom TreeView's Selected Item in Treeview programmtically

I created a WPF application where I create a list of items to be executed, as a Treeview. On a click event, I parse the ObservableCollection items one by one. This observableCollection is set as the DataContext for the treeview. When running the tests, I want to highlight the current running item in the Treeview.
I have the implemented following code, but the highlighting on the Treeview (visuallY) does not seem to happen. I checked that the "IsSelected" property does get set/unset as programmed.
I am not sure were I went wrong. Could you point out where the mistake is.
I have this class used as a DataContext to the TreeView (named mainTree).
class mytreefile : INotifyPropertyChanged
{
private string _name { get; set; }
public ObservableCollection <mytreefile> children { get; set; }
bool? _isSelected = false;
public bool? IsSelected
{
get { return _isSelected; }
set { SetIsSelected(value); }
}
void SetIsSelected(bool? val)
{
_isSelected = val;
}
public mytreefile(string value)
{
_name = value;
children = new ObservableCollection<mytreefile>();
}
void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
The XAML file is
<Grid.Resources>
<ResourceDictionary>
<HierarchicalDataTemplate x:Key="tvTemplate" ItemsSource="{Binding children, Mode=TwoWay}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{Binding _name, Mode=TwoWay}" Margin="2,0" />
</StackPanel>
</HierarchicalDataTemplate>
</ResourceDictionary>
</Grid.Resources>
<TreeView x:Name="mainTree" Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Background="WhiteSmoke"
Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Margin="1,0,2,0" SelectedItemChanged="mainTree_SelectedItemChanged"
ItemTemplate="{StaticResource tvTemplate}"
ItemsSource="{Binding}" DataContext="{Binding nodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="FontWeight" Value="Normal" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
And my MainWindow code is:
public partial class MainWindow : Window
{
ObservableCollection<mytreefile> nodes = new ObservableCollection<mytreefile>();
mytreefile mtf = null;
Thread thThread = null;
int gnCount = 0;
private void LoadTree ()
{
mytreefile tf1 = new mytreefile("Group1");
nodes.Add(tf1);
mytreefile subtf1 = new mytreefile("Sub Item 1");
mytreefile subtf2 = new mytreefile("Sub Item 2");
mytreefile subtf3 = new mytreefile("Sub Item 3");
mytreefile subtf4 = new mytreefile("Sub Item 4");
tf1.children.Add(subtf1); tf1.children.Add(subtf2); tf1.children.Add(subtf3); tf1.children.Add(subtf4);
maintree.DataContext = nodes;
}
private void OnButton1_click()
{
mtf = nodes.ElementAt(0);
gnCount = 0;
thThread = new Thread(new ThreadStart(this.myThread));
thThread.Start();
}
public void myThread ()
{
for (int i = 0; i < 3; i++)
{
Thread.Sleep(1000);
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send,
new Action(() => SetTreeItem(i)));
}
}
public void SetTreeItem(int i)
{
if (gnCount > 0) {
mytreefile mtreeitem = mtf.children.ElementAt(gnCount-1);
mtreeitem.IsSelected = false;
}
mytreefile mtreeitem = mtf.children.ElementAt(gnCount++);
mtreeitem.IsSelected = true;
}
}
The problem was with the "mytreefile" class.
The below class works fine. The way the "IsSelected" implementation was done made the difference. Posting the code for reference.
class mytreefile : INotifyPropertyChanged
{
private string _name { get; set; }
public ObservableCollection <mytreefile> children { get; set; }
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != this._isSelected)
{
this._isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
}
public mytreefile(string value)
{
_name = value;
children = new ObservableCollection<mytreefile>();
}
void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}

Custom Datagrid OnKeyDown check IsEnabled Items

I have a data grid with Static Data and two of the items are disabled. The only issue is with Silverlight when using the arrow keys to navigate thru the data grid items the disabled items also get focused on.
I have created a custom data grid class and referenced it in the XAML, and then when using the OnKeyDown event I check for IsEnabled True or False. but so far it is not getting the correct values and I think it is because Where I set the IsEnabled status I am referencing the default Datagrid class?
CustomDataGrid
public class CustomGrid : DataGrid
{
protected override void OnKeyDown(KeyEventArgs e)
{
if(IsEnabled != false)
base.OnKeyDown(e);
}
}
Xaml
<UserControl.Resources>
<Style x:Key="DataGridStyle1" TargetType="local:CustomGrid">
<Setter Property="RowStyle">
<Setter.Value>
<Style TargetType="sdk:DataGridRow">
<Setter Property="IsEnabled" Value="{Binding enabled}"/> //CheckIsEnabled Value
</Style>
</Setter.Value>
</Setter>...
<local:CustomGrid x:Name="McDataGrid" HorizontalAlignment="Left" Height="500" VerticalAlignment="Top" Width="400" Style="{StaticResource DataGridStyle1}"/>
List Data
private List<Model> Data()
{
list.Add(new Model(1, "Test", "1", true));
list.Add(new Model(2, "Ger", "2", true));
list.Add(new Model(3, "dsg", "3", true));
list.Add(new Model(4, "Hd", "4", false));
list.Add(new Model(5, "TeHRFdgst", "5", false));
return list;
}
public class Model : INotifyPropertyChanged
{
public bool _enabled;
public int Id { get; set; }
public string Name { get; set; }
public string Prop { get; set; }
public bool enabled
{
get { return _enabled; }
set
{
_enabled = value;
OnPropertyChanged("enabled");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Model(int id, string name, string prop, bool isenabled)
{
Id = id;
Name = name;
Prop = prop;
enabled = isenabled;
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
When I change this <Style TargetType="sdk:DataGridRow"> part with "local:CustomGrid" my entire grid just go blank not to sure why.
Is there any advice on how to accomplish this or maybe a different method?
Try something like this:
public class CustomGrid : DataGrid
{
private List<Model> models;
public CustomGrid()
{
Loaded += (s,e) => models = ItemsSource as List<Model>;
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (models == null)
return;
Model model = CurrentItem as Model;
if (model == null)
return;
int index = models.IndexOf(model);
switch (e.Key)
{
case Key.Down:
//is the next model disabled?
if (index < models.Count - 1 && !models[index + 1].enabled)
e.Handled = true;
break;
case Key.Up:
if (index > 0 && !models[index - 1].enabled)
e.Handled = true;
break;
}
}
}
XAML:
<UserControl ...>
<UserControl.Resources>
<Style x:Key="DataGridStyle1" TargetType="local:CustomGrid">
<Setter Property="RowStyle">
<Setter.Value>
<Style TargetType="sdk:DataGridRow">
<Setter Property="IsEnabled" Value="{Binding enabled}"/>
</Style>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<local:CustomGrid x:Name="McDataGrid" Style="{StaticResource DataGridStyle1}" />
</Grid>
</UserControl>

How to bind a command and data in a single control?

I am writing a custom control for a project. The control will hold a dropdown combobox and a datagrid. This control will be used throughout the project. On the control I am exposing the SelectedDate and the SelectedDateChangedCommand as dependency properties. When the user selects a date the main programs Model would update it's list of information for the relevant date.
When I use that control in my project the data (SelectedDate) should come from the model but the command (SelectedDateChangedCommand) should come from the ViewModel. How do I bind the data to the Model and the command to the ViewModel?
Basically, if I want to bind the content AND command of the same button, what do I do?
EDIT:
Ok, I don't think I'm explaining this very well. I'm not using a framework or template or anything like that. Maybe my problem was mentioning the UserControl. My issue is not in writing the UserControl. My issue is from the outside of the control. I don't have a code example because that is my question: how do I do this? If I were to have some sort of code it would be like this:
<Button Content="{Binding Model.SelectedDate]" Command="{Binding ViewModel.SelectedDateChanged}" />
How do I bind two properties on a control that are on two different classes?
Wow, even asking questions is difficult in WPF. :)
Ok if I understand you, you want to create a cc. Then Run bind to DateTime to your SelectedDate on your vm, and invoke a command from the control to the vm? I made a simple example for you here, I hope I understood you correctly. I simplified this example by just using a datepicker. I am using galasoft MVVM Light here. Change the content to what you want. Hope I didn't get you completely wrong :)
Generic.xaml
<Style TargetType="{x:Type local:YourCustControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:YourCustControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid >
<DatePicker x:Name="PART_DatePicker"
SelectedDate="{Binding Path=YourDateTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:YourCustControl}}}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CustControl
[TemplatePart(Name = "PART_DatePicker", Type = typeof (DatePicker))]
public class YourCustControl : Control
{
public static readonly DependencyProperty SelectedDateChangedCommandProperty = DependencyProperty.Register("SelectedDateChangedCommand", typeof (ICommand), typeof (YourCustControl), new PropertyMetadata(null));
public static readonly DependencyProperty YourDateTimeProperty = DependencyProperty.Register("YourDateTime", typeof (DateTime), typeof (YourCustControl), new PropertyMetadata(null));
private DatePicker datePicker;
static YourCustControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (YourCustControl), new FrameworkPropertyMetadata(typeof (YourCustControl)));
}
public ICommand SelectedDateChangedCommand
{
get { return (ICommand) GetValue(SelectedDateChangedCommandProperty); }
set { SetValue(SelectedDateChangedCommandProperty, value); }
}
public DateTime YourDateTime
{
get { return (DateTime) GetValue(YourDateTimeProperty); }
set { SetValue(YourDateTimeProperty, value); }
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
datePicker = (DatePicker) Template.FindName("PART_DatePicker", this);
if (datePicker != null)
{
datePicker.SelectedDateChanged += datePicker_SelectedDateChanged;
}
}
private void datePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
// Execute the command
if (SelectedDateChangedCommand != null && SelectedDateChangedCommand.CanExecute(e) && !e.Handled)
SelectedDateChangedCommand.Execute(e);
}
}
ViewModel
// replace with whatever, like extend Galasoft's ViewModelBase
public class YourViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] // Remove if no R#
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class YourViewModel : YourViewModelBase
{
private DateTime dateTime;
public DateTime DateTime
{
get { return dateTime; }
set
{
if (value.Equals(dateTime)) return;
dateTime = value;
OnPropertyChanged();
}
}
public ICommand SelectedDateChangedCommand { get; set; }
public YourViewModel()
{
SelectedDateChangedCommand = new RelayCommand<SelectionChangedEventArgs>(OnSelectedDateChanged);
}
private void OnSelectedDateChanged(SelectionChangedEventArgs e)
{
if (e != null)
e.Handled = true; // dirty hack
// do stuff here
}
}
Finally your xaml
<Grid>
<local:YourCustControl SelectedDateChangedCommand="{Binding SelectedDateChangedCommand}"
YourDateTime="{Binding DateTime, Mode=TwoWay}"/>
</Grid>
Hope it helps!
Cheers

Textbox Event Handling in ViewModel

I have a situation, where I am validating a textbox for enabling the button. If the textbox is empty the button should be disabled and vice verse. I can handle the code and achieve the solution, if I write the logic in the code behind of the XAML but I feel thats not the correct way and the event should be handled from the viewModel instead of the code behind.
Here is what I have done:
XAML
<TextBox Grid.Row="1" Margin="6,192,264,0" Height="60" VerticalAlignment="Top"
x:Name="txtDNCNotes" Text="{Binding Path=DNCNotes, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
TextWrapping="Wrap" VerticalScrollBarVisibility="Auto"
Visibility="{Binding Path=DNCNoteTxtVisibility}" Grid.Column="1"
behaviour:TextBoxFilters.IsBoundOnChange="True"
TextChanged="TextBox_TextChanged" />
ViewModel
public string DNCNotes
{
get { return _dncNotes; }
set {
if (_dncNotes == value) return;
_dncNotes = value;
OnPropertyChanged("DNCNotes");
}
}
Code behind
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var ctx = LayoutRoot.DataContext as NextLeadWizardViewModel;
BindingExpression binding = txtDNCNotes.GetBindingExpression(TextBox.TextProperty).UpdateSource();
ctx.ShowDoNotContact();
}
I am trying to write following code in the viewModel to achieve the solution but not sure what to write.
public void ShowDoNotContact()
{
Binding myBinding = new Binding("DNCNotes");
//myBinding.Source = DataContext as NextLeadWizardViewModel;
myBinding.Source = txtDNCNotes;
myBinding.Path = new PropertyPath("DNCNotes");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(txtDNCNotes, TextBox.TextProperty, myBinding);
if (_dncNotes == null)
OkCommand.IsEnabled = false;
else
OkCommand.IsEnabled = CanEnableOk();
}
If you want to validate a TextBox which would disable the button, i would use a command, something similar to this;
private ICommand showDCNoteCommand;
public ICommand ShowDCNoteCommand
{
get
{
if (this.showDCNoteCommand == null)
{
this.showDCNoteCommand = new RelayCommand(this.DCNoteFormExecute, this.DCNoteFormCanExecute);
}
return this.showDCNoteCommand;
}
}
private bool DCNoteFormCanExecute()
{
return !string.IsNullOrEmpty(DCNotes);
}
private void DCNoteFormExecute()
{
DCNoteMethod(); //This a method that changed the text
}
This would ensure that the user is unable to continue, or save to progress as the TextBox should not accept a null or empty value, shown within the DCNoteFormCanExecute() (the DCNotes is property that you have defined within your Viewmodel).
and in the xaml, bind it to the button like so;
<Button Content="Save" Grid.Column="1" Grid.Row="20" x:Name="btnSave" VerticalAlignment="Bottom" Width="75" Command="{Binding ShowDCNoteCommand}"
For validation, you could do something simple like so, using attribute validation, using this reference using System.ComponentModel.DataAnnotations;
[Required(ErrorMessage = "DCNotes is required")]
[RegularExpression(#"^[a-zA-Z''-'\s]{1,5}$", ErrorMessage = "DCNotes must contain no more then 5 characters")] //You can change the length of the property to meet the DCNotes needs
public string DCNotes
{
get { return _DCNotes; }
set
{
if (_DCNotes == value)
return;
_DCNotes = value;
OnPropertyChanged("DCNotes");
}
}
and within the xaml, you could create a Resource to highlight the box to notify the user of the textbox not been filled out;
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin"
Value="4" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin"
Value="4" />
<Style.Triggers>
<Trigger Property="Validation.HasError"
Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
I hope this helps, otherwise, here's the link that might help;
http://www.codeproject.com/Articles/97564/Attributes-based-Validation-in-a-WPF-MVVM-Applicat
OR
http://www.codearsenal.net/2012/06/wpf-textbox-validation-idataerrorinfo.html#.UOv01G_Za0t
The ViewModel is an acceptable place to add supporting properties for your View that do not effect your model. For example, something along the lines of:
public bool DncCanExecute
{
get
{
return "" != _dncNotes;
}
}
public string DNCNotes
{
get { return _dncNotes; }
set {
if (_dncNotes == value) return;
if (("" == _dncNotes && "" != value) || ("" != _dncNotes && "" == value))
{
_dncNotes = value;
OnPropertyChanged("DncCanExecute");
}
else
{
_dncNotes = value;
}
OnPropertyChanged("DNCNotes");
}
}
From there, you can just bind the Button.IsEnabled property to the DncCanExecute property to get the desired functionality.

WPF Menu Binding losing style only in the first level

Please let me know if I am doing something wrong in my code. I am trying to bind a WPF menu to a "MenuViewModel". The binding works as I expect in a non styled Window.
I am using MahApps.Metro for styling purposes only and this is how it looks after binding.
Here's the link to the source code http://sdrv.ms/W5uJpY
ViewModel:
public class Menu : INotifyPropertyChanged
{
public Menu()
{
IsEnabled = true;
Children = new List<Menu>();
}
#region [ Menu Properties ]
private bool _isEnabled;
private string _menuText;
private ICommand _command;
private IList<Menu> _children;
public string MenuText
{
get { return _menuText; }
set
{
_menuText = value;
RaisePropertyChanged("MenuText");
}
}
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
RaisePropertyChanged("IsEnabled");
}
}
public ICommand Command
{
get { return _command; }
set
{
_command = value;
RaisePropertyChanged("Command");
}
}
public IList<Menu> Children
{
get { return _children; }
set
{
_children = value;
}
}
#endregion
#region [INotifyPropertyChanged]
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
XAML:
<Menu Grid.Row ="0" IsMainMenu="True" x:Name="mainMenu" VerticalAlignment="Top" ItemsSource="{Binding Children}">
<Menu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<!--Or can be the line below, both yield the same result-->
<!--<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MetroMenuItem}">-->
<!--NOTICE THAT SUB MENU's of OPEN work fine-->
<Setter Property="Header" Value="{Binding Path=MenuText}"/>
<Setter Property="Command" Value="{Binding Path=Command}"/>
<Setter Property="ItemsSource" Value="{Binding Path=Children}"/>
</Style>
</Menu.ItemContainerStyle>
</Menu>
I think I found an answer here
http://karlshifflett.wordpress.com/2008/02/03/wpf-sample-series-databound-hierarchicaldatatemplate-menu-sample/
It does the binding correctly - along with maintaining Separators.

Categories

Resources