2015-01-20 4 views
0

ListView가있는 프로젝트가 있으며 사용자가 New 버튼을 클릭하면 ListView의 아래쪽에 새 Object가 추가됩니다. Content Style 클래스를 사용해 보았지만 작동하지 않았습니다. 선택한 항목으로 스크롤 할 항목이 필요합니다. 다음은 내 코드입니다 :MVVM Light의 목록 뷰에 새 항목을 추가하는 방법

보기 : 새 버튼에 대한

<ListView Margin="103,0,0,10" ScrollViewer.CanContentScroll="True" Height="87" SelectedItem="{Binding SelectedSession, Mode=TwoWay}" ItemsSource="{Binding SessionCollection}"> 
    <ListView.Resources> 
     <Style TargetType="{x:Type GridViewColumnHeader}"> 
      <Setter Property="HorizontalContentAlignment" Value="Left" /> 
     </Style> 
    </ListView.Resources> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Session Name" Width="180" DisplayMemberBinding="{Binding SessionName, Mode=TwoWay}" /> 
      <GridViewColumn Header="Operator Name" Width="180" DisplayMemberBinding="{Binding OperatorName, Mode=TwoWay}"/> 
      <GridViewColumn Header="Session Date" Width="180" DisplayMemberBinding="{Binding SessionDate, Mode=TwoWay}"/> 
     </GridView> 
    </ListView.View> 
</ListView> 

보기 모델 코드 : 행동

public void NewSession() 
{ 
    Session newSession = new Session(); 

    SessionCollection.Add(newSession); 
    SelectedSession = newSession; 
    SessionDate = DateTime.Now; 
    StartTime = DateTime.Now; 
    EndTime = DateTime.Now; 
    ProjectManager.Instance.CurrentSession = null; 
} 

public ObservableCollection<Session> SessionCollection 
{ 
    get 
    { 
     if (currentDatabaseProj.Sessions == null) 
     { 
      return currentDatabaseProj.Sessions; 
     } 
     else 
     { 
      return currentDatabaseProj.Sessions; 
     } 
    } 
    private set 
    { 
     currentDatabaseProj.Sessions = value; 
     IsNewProjClicked = true; 
     this.RaisePropertyChanged("SessionCollection"); 
    } 
} 
+0

맞으면 "새 버튼"을 클릭 할 때 선택한 항목을 새 요소로 설정하고 있습니까? – Herdo

+0

예. 맞아. – yams

+0

'SelectedItem'을 설정해도 자동으로 포커스가 지정되지 않습니다. 자세한 내용은 설정 방법을 보려면 [this] (http://stackoverflow.com/a/11747701/2132796) 항목을 참조하십시오. – Herdo

답변

1

뒤에 트릭 (내가 만든 분명히 당신의 코드를 단순화)

<Grid x:Name="LayoutRoot"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 
    <ListView x:Name="listView" Margin="10" ScrollViewer.CanContentScroll="True" SelectedItem="{Binding SelectedSession, Mode=TwoWay}" ItemsSource="{Binding SessionCollection}"> 
     <ListView.Resources> 
      <Style TargetType="{x:Type GridViewColumnHeader}"> 
       <Setter Property="HorizontalContentAlignment" Value="Left" /> 
      </Style> 
     </ListView.Resources> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="Session Name" Width="180" DisplayMemberBinding="{Binding}" /> 
      </GridView> 
     </ListView.View> 
    </ListView> 
    <Button Click="UIElement_NewElementHandler" Grid.Row="1" Content="Add Item" Command="{Binding AddItem}"></Button> 
</Grid> 

와 뷰의 코드 뒤에 다음 핸들러 추가에해야 할 코드의 하나의 간단한 핸들러 :

private void UIElement_NewElementHandler(object sender, RoutedEventArgs routedEventArgs) 
    {    
     var border = VisualTreeHelper.GetChild(listView, 0) as Decorator;    
     var scrollViewer = border.Child as ScrollViewer; 
     scrollViewer.ScrollToBottom(); 
    } 

ps : 새로 추가 된 항목으로 스크롤하는 것은 ViewRelated인데,보기 모델 속성 중 아무 것도 코드 숨김에 사용되지 않으므로 그렇게하지 않아도 mvvm 규칙을 위반하지 않았다고 생각합니다.

+0

나는 그것을 지금 시도 할 것이다. – yams

+0

고마워요. 그것은 일관되게 일했습니다. – yams

0

작업을 예를

XAML

<Window x:Class="ListView.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:listView="clr-namespace:ListView" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <Button Content="Add New" Grid.Row="0" Click="Button_Click"></Button> 
    <ListView Grid.Row="1" ItemsSource="{Binding MySessionList}" SelectedItem="{Binding SelectedSession, Mode=TwoWay}"> 
     <i:Interaction.Behaviors> 
      <listView:ScrollIntoViewBehavior/> 
     </i:Interaction.Behaviors> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="Name" Width="200" DisplayMemberBinding="{Binding Name, Mode=TwoWay}" /> 
      </GridView> 
     </ListView.View> 
    </ListView> 
</Grid> 
</Window> 

CS

public partial class MainWindow : Window 
{ 
    private Viewmodel _data; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     _data = new Viewmodel(); 
     this.DataContext = _data; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     _data.AddNew(); 
    } 
} 

public class Viewmodel : INotifyPropertyChanged 
{ 
    private MySession _selectedSession; 
    public ObservableCollection<MySession> MySessionList { get; set; } 

    public Viewmodel() 
    { 
     this.MySessionList = new ObservableCollection<MySession>(); 

     //fill with some data 
     for (int i = 0; i < 20; i++) 
     { 
      this.MySessionList.Add(new MySession(){Name = "Index : " + i}); 
     } 
    } 

    public MySession SelectedSession 
    { 
     get { return _selectedSession; } 
     set 
     { 
      _selectedSession = value; 
      OnPropertyChanged(); 
     } 
    } 

    //should be a Command for MVVM but for quick and dirty 
    public void AddNew() 
    { 
     var toAdd = new MySession() {Name = "New Added " + DateTime.Now.ToLongTimeString()}; 
     this.MySessionList.Add(toAdd); 
     this.SelectedSession = toAdd; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

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

//ADD REFERENCE: System.Windows.Interactivity 
public class ScrollIntoViewBehavior : Behavior<ListBox> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged; 
    } 

    private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     var ctrl = sender as ListBox; 

     if (ctrl == null) 
      return; 


     if (ctrl.SelectedItem != null) 
     { 
      ctrl.Dispatcher.BeginInvoke(
       DispatcherPriority.Render, 
       new Action(() => 
       { 
        ctrl.UpdateLayout(); 
        ctrl.ScrollIntoView(ctrl.SelectedItem); 
       })); 
     } 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged; 
    } 
} 
+0

하나의 질문은이 버튼을 클릭하여 렌치를 던지는 새 세션에 대한 코드입니다. 새 세션 객체를 만들고 SelectedSession = newSession;을 설정할 위치 – yams

+0

또한 Behaviors 추가 기능을 어디에서 얻을 수 있습니까? ScrollIntoViewBehavior가 wpf에서 지원되지 않는 의 내 xaml에서 오류가 발생합니까? – yams

+0

Visual Studio 2013에서 Behaviors.Scrollintoviewbehavior가 지원되지 않는다는 오류가 발생한다는 것을 알고 있습니다. – yams