|
I'm not that familiar with whichever RelayCommand implementation you're using (I've developed my own ways of organizing command-bindings), but the XAML is just:
CommandParameter="{Binding}"
But if it was a normal RoutedEventHandler, it would look something like:
private void ExecuteMyCommand(object sender, ExecutedRoutedEventArgs e)
{
MyModelClass modelItem = (MyModelClass)(e.Parameter);
}
|
|
|
|
|
I think you got that from me lol. From the code you posted, it seems like you didn't bind the treeview's selected item to the VM.
|
|
|
|
|
Actually I had this earlier...
<controls:TreeViewEx ItemsSource="{Binding TreeItems}"
SelectedItemEx="{Binding SelectedTreeLink}"/>
but it didn't change anything so I removed it.
and here's the TreeViewEx. Is this your code?
public class TreeViewEx : TreeView
{
public static readonly DependencyProperty SelectedItemExProperty = DependencyProperty.Register("SelectedItemEx", typeof(object),
typeof(TreeViewEx), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemExChanged)));
public TreeViewEx()
: base()
{
SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(TreeViewEx_SelectedItemChanged);
}
public object SelectedItemEx
{
get { return (object)GetValue(SelectedItemExProperty); }
set { SetValue(SelectedItemExProperty, value); }
}
public bool SelectItem(object item)
{
if ((SelectedItem != null) && (SelectedItem.Equals(item)))
return true;
if (!ExpandAndSelectItem(this, item))
{
UpdateLayout();
return ExpandAndSelectItem(this, item);
}
return true;
}
private static void OnSelectedItemExChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TreeViewEx treeView = d as TreeViewEx;
if ((object)treeView != null)
treeView.SelectItem(e.NewValue);
}
private void TreeViewEx_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SetValue(SelectedItemExProperty, e.NewValue);
}
private bool ExpandAndSelectItem(ItemsControl parentContainer, object itemToSelect)
{
TreeViewItem tvi = parentContainer.ItemContainerGenerator.ContainerFromItem(itemToSelect) as TreeViewItem;
if ((object)tvi != null)
{
tvi.IsSelected = true;
tvi.BringIntoView();
tvi.Focus();
return true;
}
for (int nIndex = 0; nIndex < parentContainer.Items.Count; nIndex++)
{
TreeViewItem currentContainer = parentContainer.ItemContainerGenerator.ContainerFromIndex(nIndex) as TreeViewItem;
if (((object)currentContainer != null) && (currentContainer.Items.Count > 0))
{
bool bIsExpanded = currentContainer.IsExpanded;
if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
EventHandler handler = null;
handler = new EventHandler(delegate
{
if (currentContainer.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
if (ExpandAndSelectItem(currentContainer, itemToSelect) == false)
currentContainer.IsExpanded = false;
currentContainer.ItemContainerGenerator.StatusChanged -= handler;
}
});
currentContainer.ItemContainerGenerator.StatusChanged += handler;
if (currentContainer.IsExpanded == false)
currentContainer.IsExpanded = true;
}
else
{
if (ExpandAndSelectItem(currentContainer, itemToSelect) == false)
currentContainer.IsExpanded = bIsExpanded;
else
return true;
}
}
}
return false;
}
}
If it's not broken, fix it until it is
|
|
|
|
|
You need to make SelectedItemEx mode=TwoWay.
|
|
|
|
|
Still no joy.
Tomorrow I'm going to abstract this out into a sandbox app. That'll allow me to work without all the other app code I have. Plus if I need to I can post the sample app for others to see.
I'll post again after that.
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
I just tested it in my test app and SelectedItemEx is working as expected. Supports 2-way binding just as it should. My TreeViewEx XAML is:
<fx:TreeViewEx Name="treeView" Grid.Row="0" Margin="20,20,20,20" SelectedItemEx="{Binding o, Mode=TwoWay}">
.
.
</fx:TreeViewEx>
and o is just an object that lives in the VM.
Some things you might want to look at:
1) make sure the DataContext is correct and you are binding to the right type of object.
2) make sure you are not setting TreeViewEx.SelectedItemEx manually... this is not an issue with my control, this is a general WPF "issue". If you have a binding set and then set the value directly, it clears the binding.
|
|
|
|
|
Oh wait...you know whats probably happening?
You click on the hyperlink, so that executes the hyperlink command, but its not selecting the TreeViewItem because the hyperlink ate it.
either:
1) make the hyperlink select the node
2) make the hyperlink pass in node in the CommandParamter
|
|
|
|
|
Ok, I see.
SledgeHammer01 wrote: make the hyperlink select the node
I had code somewhere to do this. Lemme look for it.
SledgeHammer01 wrote: make the hyperlink pass in node in the CommandParamter
Interesting idea. Can you share how to do this?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
Ok, I created a sandbox app[^] and I figured out what's happening.
See this[^]
Then this[^]
The node has to be clicked first.
Yesterday you suggested making the hyperlink select the node. This seems like a decent approach, although I could use some help with it.
Many thanks
If it's not broken, fix it until it is
|
|
|
|
|
Probably in the hyperlink xaml, add a CommandParamter="{Binding}". You'll need to use RelayCommand<T> instead of RelayCommand though. RelayCommand<RoutedEventArgs> I suppose. That should contain the VM for the node.
|
|
|
|
|
That did it!
_SelectedLinkCommand = new RelayCommand<NodeModel>(p => selectedTreeItemExecuted(p), p => selectedTreeItemCanExecute(p));
Worked like a charm. Thanks
ya know, I notice that there's not alot on CP about a TreeView with Hyperlinks. Maybe I'll turn this into an article. WHat do ya think?
If it's not broken, fix it until it is
|
|
|
|
|
What's the difference?
I can't seems to find a difinitive description.
If it's not broken, fix it until it is
|
|
|
|
|
Don't know if there is a definitive description but the Application template is the most basic and provides limited boilerplate code to get started. The Business Application template throws in a whole lot of extra boilerplate providing functionality that a typical LOB application.
Quote from Walkthrough: Using the Silverlight Business Application Template[^]
"The Silverlight Business Application template creates a project that automatically includes many features that you typically want in a business application, such as controls to log in users and to register new users. The project created by the template is also set up to use Silverlight navigation, which means you can easily add new Silverlight pages for additional functionality."
"You get that on the big jobs."
|
|
|
|
|
|
I have had an odd request and just cant find any info on how (or even if) this can be done.
I am using the wpf toolkit charting controls to create a column chart. This bit is simple enough but what about showing columns in columns. The data i am using is like this:
Group
- GroupName
- Strength
- GroupItems()
GroupItem
- ItemName
- ItemStrength
So i have an observble collection of 'Groups' which is the itemsource for my column chart using the groupname as the independent and the Strength as the dependent. This works fine.
What you can see though is that each group also has a collection of 'GroupItems' (there can be 2 to 5 of these per group). What i would like is that within the outline of the 'Group' column i can see the columns for the 'GroupItems' that belong to that group.
Is this even possible?
|
|
|
|
|
Working on a WPF MVVM app...
I have this button:
<Button Background="Transparent"
BorderBrush="Transparent"
Command="{Binding RunCommand}"
Margin="2"
Width="120"
Height="40">
<StackPanel Orientation="Horizontal">
<Image Source="/DemoUI;component/Images/run.png"
Height="32"
Width="32"
Margin="3"/>
<TextBlock Text="Run Test"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
It's bound to RunCommand:
private ICommand _RunCommand;
public ICommand RunCommand
{
get
{
if (_RunCommand == null)
{
_RunCommand = new RelayCommand(runTest, runTestCanExecute);
}
return _RunCommand;
}
}
Here's the methods:
private void runTest()
{
isTesting = true;
var device = (from d in tempDevices
where d.DeviceId == SelectedDevice.DeviceId
select d).FirstOrDefault();
diag.ExecuteTest(device, SelectedTest);
}
private bool runTestCanExecute()
{
return !isTesting;
}
isTesting is defaulted to False. The button does not disable.
Anyone see what's wrong?
If it's not broken, fix it until it is
modified 11-Jul-12 14:53pm.
|
|
|
|
|
Are you sure its not disabled? You are overriding the content, so it may appear to be enabled, but really be not clickable because you aren't handling the disabled state.
|
|
|
|
|
Ya, it's still responds to clicks.
If it's not broken, fix it until it is
|
|
|
|
|
Copy & pasted your code into a test project and it disables just fine. Make sure your DataContext is set properly or it won't know where the command is. I.e. put a break point on your CanExecute handler and make sure its actually getting called.
|
|
|
|
|
Ok, I see what's going on. isTesting is somehow reverting to false by the time the CanExecute is called.
Stay tuned.....
If it's not broken, fix it until it is
|
|
|
|
|
Try this, change you button to use a Click="" event instead of a Command.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I haven't got VS at hand at the moment but couldn't you just do something along the lines of:
<Button IsEnabled="{Binding RunTestButtonEnabled} /Button>
Where RunTestButtonEnabled is a property in your ViewModel.
"You get that on the big jobs."
|
|
|
|
|
Whenever you change isTesting you will need to call
RunCommand.OnCanExecuteChanged()
(If it isn't, you might want to make isTesting a property and call OnExecuteChanged from the Setter)
|
|
|
|
|
Hi All,
I am using datagrid in wpf.actually my requirement is used to show different color in particular cell after every two minutes like first two minutes we need to show blue then Red but values in that cell should not get changed.I have shown the color in the cell using datatrigger through Xaml but i need to add that dynamically into the datatemplate and show the cell coloring.so,if any one knows about this please help me out of it.
Thanks in Advance
Palaniappan
|
|
|
|
|
OK, this is fairly simple to achieve with the use of a Timer, a public property and a value converter. What you need to do is create a property that you will bind to as part of the collection that you are binding your DataGrid against. The timer will be used to change the value of the property.
The value converter simply converts this value into an appropriate colour. Your Background will be bound to the property, and you will use the value converter as your converter.
|
|
|
|