Change ListBox.ItemsSource Binding property on Button.Click?
Quick question...
I have a ListBox
with its ItemsSource
property bound to a collection property in a viewmodel like so:
<ListBox Name="CollectionsListBox" ItemsSource="{Binding Activity.Timesheets}" />
I also have two Button
objects in the same view. The question is... can I change the CollectionsListBox
ItemsSource Binding
from Activity.Timesheets
to Activity.Attachments
using just XAML?
Failing that, from the viewmodel using Command objects?
EDIT >>>
I found a simple solution by using RadioButton
s instead of Button
s from part of Howard's answer:
<ListBox Name="CollectionsListBox">
<ListBox.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TimesheetsButton,Path=IsChecked}" Value="True">
<Setter Property="ListBox.ItemsSource" Value="{Binding Activity.Timesheets}" />
<Setter Property="ListBox.ItemContainerStyle" Value="{StaticResource TimesheetStyle}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=AttachmentsButton,Path=IsChecked}" Value="True">
<Setter Property="ListBox.ItemsSource" Value="{Binding Activity.Attachments}" />
<Setter Property="ListBox.ItemContainerStyle" Value="{StaticResource AttachmentStyle}" />
</DataTrigger>
</Style.Triggers>
</开发者_运维技巧Style>
</ListBox.Style>
</ListBox>
Many thanks for the help.
I'm not sure if Button can do this. But radiobutton can satisfy you only in XAML.
Let's say we have two enum:
public enum E { A = 0, B = 1, C = 2 }
public enum F { G = 0, H = 1, L = 2 }
I defined them as resource in the XAML:
<ObjectDataProvider ObjectType="{x:Type sys:Enum}" MethodName="GetValues" x:Key="EProvider">
<ObjectDataProvider.MethodParameters>
<x:TypeExtension Type="{x:Type local:E}" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider ObjectType="{x:Type sys:Enum}" MethodName="GetValues" x:Key="FProvider">
<ObjectDataProvider.MethodParameters>
<x:TypeExtension Type="{x:Type local:F}" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
Then here we go:
<ListBox x:Name="List1">
<ListBox.Style>
<Style>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Rdb1,Path=IsChecked}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="ListBox.ItemsSource" Value="{Binding Source={StaticResource EProvider}}" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Rdb2,Path=IsChecked}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="ListBox.ItemsSource" Value="{Binding Source={StaticResource FProvider}}" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
<RadioButton x:Name="Rdb1" GroupName="Group1" />
<RadioButton x:Name="Rdb2" GroupName="Group1" />
As much I understand this is what you need -
Here is how i did
1)Code Behind (with two enums)
public enum Enum1{R = 0, O = 1,H = 2,I = 3,T = 4}
public enum Enum2{A = 0,S = 1, I = 2,T = 3}
public partial class Window1 : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool toggleItemSource;
public bool ToggleItemSource
{
get
{
return this.toggleItemSource;
}
set
{
this.toggleItemSource = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("ToggleItemSource"));
}
}
public Window1()
{
InitializeComponent();
this.DataContext = this;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.ToggleItemSource = this.ToggleItemSource ? false : true;
}
}
XAML
<Window x:Class="Listbox_with_dynamic_data_source.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Listbox_with_dynamic_data_source"
Title="Window1" Height="300" Width="300">
<ObjectDataProvider ObjectType="{x:Type sys:Enum}"
MethodName="GetValues"
x:Key="Enum2Provider">
<ObjectDataProvider.MethodParameters>
<x:TypeExtension Type="{x:Type local:Enum2}" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<!-- ListBox-->
<ListBox x:Name="DynamicListBox"
Padding="10" HorizontalAlignment="Left" Width="52" Margin="20,21,0,115">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="ItemsSource"
Value="{Binding Source={StaticResource Enum1Provider}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ToggleItemSource,
UpdateSourceTrigger=PropertyChanged
}"
Value="False">
<Setter Property="ItemsSource"
Value="{Binding Source={StaticResource Enum2Provider}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
<!-- Toggle Button -->
<Button Height="29"
Margin="94,45.44,59,0"
Name="button1"
VerticalAlignment="Top"
Click="button1_Click"
Content="ToggleItemSource" />
</Grid>
Clicking on Toggle Item Source Button will toggle the Items Source
To my surprise the following seems to work:
<ListBox Name="myLB" ItemsSource="{Binding Data}"/>
<Button Content="This is a Button">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="myLB"
Storyboard.TargetProperty="ItemsSource">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding Data2}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
Edit: If this works apparently depends on the nature of the itemssource. Animations are a bit messy in that regard. Using constant states is better e.g. as suggested with Radiobuttons since then Setters can be used.
精彩评论