Привязка к CurrentItem в ItemsControl - PullRequest
       39

Привязка к CurrentItem в ItemsControl

3 голосов
/ 21 декабря 2009

XAML, приведенный ниже, в основном пытается создать список Button s (отображается из свойства Name объектов в коллекции Views в текущем DataContext.

Когда я нажимаю на кнопку, свойство CurrentItem, равное CollectionViewSource, должно измениться, и соответствующее View должно отображаться в представителе содержимого.

OK. Если я нажму на ListBox в XAML ниже, он будет работать точно так, как нужно.

Но, если я нажму кнопку в UniformGrid (созданном с помощью элемента управления), свойство CurrentItem не будет обновлено.

Как получить CurrentItem для обновления, когда элемент выбран в ItemsControl?

Спасибо

<UserControl x:Class="Pos.Features.Reservation.ReservationView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:product="clr-namespace:Pos.Features.ProductBrowser"
             xmlns:activity="clr-namespace:Pos.Features.ActivityBrowser"
             xmlns:addbysku="clr-namespace:Pos.Features.AddBySku"
             xmlns:client="clr-namespace:Pos.Features.ClientBrowser"
             xmlns:notes="clr-namespace:Pos.Features.Notes"
             xmlns:controls="clr-namespace:Pos.Views"
             xmlns:res="clr-namespace:Pos.Core;assembly=Pos.Core"
             Height="300" Width="300">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type product:ProductBrowserViewModel}">
            <product:ProductBrowserView/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type activity:ActivityBrowserViewModel}">
            <activity:ActivityBrowserView/>
        </DataTemplate>

        <CollectionViewSource x:Name="x" x:Key="ViewsCollection" Source="{Binding Views}"  />
    </UserControl.Resources>

    <StackPanel>
        <ListBox Name="ListBoxMenu" Grid.Column="0" Margin="5" ItemsSource="{Binding Source={StaticResource ViewsCollection}}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Padding="10"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ContentControl Grid.Column="1" Content="{Binding ElementName=ListBoxMenu, Path=SelectedItem}"/>
        <ItemsControl  Grid.Column="2" Name="ViewList" ItemsSource="{Binding Source={StaticResource ViewsCollection}}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button>
                        <TextBlock Text="{Binding Path=Name}" Name="txtButtonLabel" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/>
                    </Button>
                </DataTemplate>                
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="1" Columns="{Binding Views.Count}"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <ContentControl Grid.Column="3" Content="{Binding Source={StaticResource ViewsCollection}, Path=CurrentItem}"/>
        <Button Grid.Column="4" Click="Button_Click">dsadsd</Button>
    </StackPanel>
</UserControl>

Ответы [ 2 ]

11 голосов
/ 21 декабря 2009

Ваша кнопка ничего не делает. Обычно ваша ViewModel будет иметь ICommand с именем Select (или что-то подобное), что Button будет привязан к

Command="{Binding Select, ElementName="root"}"

и вы передадите экземпляр ICommand, который хотите выбрать

CommandParameter="{Binding}"

Это будет выглядеть примерно так (c # / XAML, как псевдокод):

public class MyModel { public string Name {get;set;} }

public class MyViewModel
{
  public ObservableCollection<MyModel> Models {get;set;}
  public ICommand Select {get;set;}
  /* configure Models and Select etc */
}

<UserControl DataContext="{StaticResource MyViewModelInstance}" x:Name="root">
<ItemsControl ItemsSource="{Binding Models}">
  <ItemsControl.ItemTemplate>
    <ItemsPanelTemplate>
      <Button Text="{Binding Name}" 
      Command="{Binding Select, ElementName="root"}"
      CommandParameter="{Binding}"/>
   </ItemsPanelTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>

ItemsControl связывается с Моделями , поэтому каждая MyModel в Моделях получает кнопку. Текст кнопки привязан к свойству Имя . Команда кнопки привязана к свойству Select в ViewModel. Когда кнопка нажата, она вызывает ICommand, отправляя в случае MyModel , с которой связана кнопка.

Обратите внимание, что использование ViewModels в UserControl - это кодовый запах . UserControl должны отображаться пользователям как все остальные элементы управления - они должны иметь привязываемые общедоступные свойства, которые привязаны к ViewModel пользователя, а не к вам. Затем вы привязываетесь к значениям этих свойств в UserControl. В этом примере у вас будет ItemsSource свойство, определенное в вашем UserControl, и ItemsControl будет привязываться к этому свойству, а не ViewModel напрямую.

1 голос
/ 21 декабря 2009

Я думаю, вы должны сделать это вручную в коде позади.

XAML

<Button Click="ViewListButton_Click">
    <TextBlock Text="{Binding Path=Name}" Name="txtButtonLabel" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black"/>
</Button>

Код-за

private void ViewListButton_Click(object sender, RoutedEventArgs e)
{
    Button button = sender as Button;
    ICollectionView view = CollectionViewSource.GetDefaultView(ViewList.ItemsSource);
    view.MoveCurrentTo(button.DataContext);
}

Если вы используете шаблон MVVM и / или не хотите использовать выделенный код, вы можете привязать Command кнопки к команде в вашей ViewModel, как предлагает Will

...