开发者

Change ListBox.ItemsSource Binding property on Button.Click?

开发者 https://www.devze.com 2023-02-28 04:39 出处:网络
Quick question... I have a ListBox with its ItemsSource property bound to a collection property in a viewmodel like so:

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 RadioButtons instead of Buttons 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 -

Change ListBox.ItemsSource Binding property on Button.Click?

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消