tags:

views:

62

answers:

2

Continuing from my last question, I'd like to know how can I bind when a button is clicked (can this be done through pure XAML?) - or more simply, how can I do XAML-like binding through C# code?

EDIT: The previous question containing info:

I want to create a listbox that'll be bound to XPath, relative to the other listbox's currently selected item.

It's using XmlDataProvider for the data, and the XML file looks like this:

<Programs>
    <Program name="...">
        <Step name="..."/>
        <Step name="..."/>
    </Program>
    <Program name="another">

    ...

</Programs>

So, the "parent" listbox is listing out all the programs, while "child" shows only Steps from the current Program. I just need a pointer on the fact what's such type of binding called.

Thanks in advance.

End of previous question

The question is how can I do a one time bind (I do not want binding to change as soon as user clicks another listbox item) when a button called "Load" is pressed?

+1  A: 

Bind the Command property to a property implementing ICommand.

Assuming you have an object (ViewModel) with property "ICommand HelloCommand { get { ... }; }" set as the data context:

<Button Content="Hello" Command="{Binding HelloCommand}"/>

The Execute method of the ICommand implementation will get called when the button is clicked. The CanExecute method should return whether the command is available and will determine the enabled status of the button.

There are also helper classes and frameworks that can make this simpler (and/or more complicated).

mancaus
Uh, what do you mean by this? All I need is C# based idea how do I assign bindings through the code.
Johnny
+1  A: 

Let's start with an example where the detail list box does change whenever the user selects an item in the master list box:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
  <Page.Resources>
    <XmlDataProvider x:Key="Programs">
      <x:XData>
        <Programs xmlns="">
          <Program name="Some program">
            <Step name="Some program step 1"/>
            <Step name="Some program step 2"/>
            <Step name="Some program step 3"/>
            <Step name="Some program step 4"/>
          </Program>
          <Program name="Some other program">
            <Step name="Some other program step 1"/>
            <Step name="Some other program step 2"/>
            <Step name="Some other program step 3"/>
            <Step name="Some other program step 4"/>
          </Program>        
        </Programs>
      </x:XData>
    </XmlDataProvider>
  </Page.Resources>
  <DockPanel>  
    <Label DockPanel.Dock="Top">Programs</Label>
    <ListBox x:Name="Program" DockPanel.Dock="Top" ItemsSource="{Binding Source={StaticResource Programs}, XPath=/Programs/Program}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding XPath=@name}"/>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
    <Label DockPanel.Dock="Top">Steps</Label>
    <ListBox x:Name="Step" DockPanel.Dock="Top" DataContext="{Binding ElementName=Program, Path=SelectedItem}" ItemsSource="{Binding XPath=Step/@name}"/>
  </DockPanel>
</Page>

What has to change in order for the detail to change only when the user clicks a button? One thing: the DataContext on the ListBox named Step. You need to use code-behind to do this, but the code is pretty simple:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (Program.SelectedItem != null)
    {
        Step.DataContext = Program.SelectedItem;
    }
}

Edit

In order for the above to work, you have to change the Step ListBox to:

<ListBox x:Name="Step" DockPanel.Dock="Top" ItemsSource="{Binding XPath=Step/@name}"/>

That ListBox won't display anything unless its DataContext is assigned.

Robert Rossney
Sorry if my next question makes no sense, but isn't that piece of XAML code going to change my step listbox each time the program listbox selection is changed?
Johnny
I should have been clearer. In the XAML, remove the binding on the `DataContext` of the step list box. Then the `DataContext` won't get changed until the button is clicked.
Robert Rossney
I have removed the DataContext binding, and made code-behind, just now nothing happens, simply bind won't work.Another question: after I'd assign DataContext to the listbox, wouldn't it simply stay and change everytime program listbox changes?I think I need explicit binding, but I'm still trying to get it working, can you give me any tips on that?
Johnny
I did test that code before posting it, so without looking at your code I can't tell you why it doesn't work. As to your second question, no. You're assigning `Step.DataContext` to one node of the XML document. Except at the moment of assignment, the `Program` list box isn't involved in any way.
Robert Rossney
Okay I think I figured what you meant, but you didn't get me.Program list box ins't involved indeed. But Step list box is! Just what happens as soon as I bind the data context (thorough the code?) My Step list box changes the very moment I next time changes selected item in the Program list box, and that's the behavior I want to avoid. My app shouldn't change program unless Load button is pressed (and some other conditions are fulfilled). I hope you understand what I mean.
Johnny
Another note: That piece of code doesn't seem to work at all curiously. I've just did a recode and did all you said.
Johnny
If you paste the XAML I posted into Kaxaml, you'll find that the Step box is synchronized with the current item in the Program box. If you then make the change I describe in my edit, it stops being synchronized. (You can use VS instead of Kaxaml, but then you'll want to make it a Window instead of a Page.)
Robert Rossney
But the C# code you provided doesn't sync it later on (I don't mean constant sync - bind, rather update). Is there any other function that should trigger temporary bind and update? It simply stays blank
Johnny
Have you set the Load button's Click property to that function?
Robert Rossney