отображение списка в сетке

#c# #wpf #listbox #grid #stackpanel

#c# #wpf #список #сетка #stackpanel

Вопрос:

Это может быть глупый вопрос, но я застрял, делая это :(. У меня есть сетка и 3 столбца. У меня есть текстовое поле и список в каждом из этих 3 столбцов, как показано:

 <Grid.ColumnDefinitions>
                <ColumnDefinition Width="130"></ColumnDefinition>
                <ColumnDefinition Width="380"></ColumnDefinition>
                <ColumnDefinition Width="146"></ColumnDefinition>
             </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="30"></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Grid.Column="0" Grid.Row="0">
                <TextBox Text="File Name" Height="30"></TextBox>
            </StackPanel>
            <StackPanel Grid.Column="1" Grid.Row="0">
                <TextBox Text="File Path" Height="30"></TextBox>
            </StackPanel>
            <StackPanel Grid.Column="2" Grid.Row="0">
                <TextBox Text="File Size" Height="30"></TextBox>
            </StackPanel>

            <StackPanel Grid.Column="0">
                <ListBox Name="listbox_name" Margin="1,30" Height="276" />
             </StackPanel>
            <StackPanel Grid.Column="1">
                <ListBox Name="listbox_path" Margin="1,30" Height="276" />
            </StackPanel>
            <StackPanel Grid.Column="2">
                <ListBox Name="listbox_size" Margin="1,30" Height="276" />
            </StackPanel>
  

и код, стоящий за ним:

 public Window1()
        {
        InitializeComponent();

        list.Add("D:\a\hy");
        list.Add("D:\a\hy1");
        list.Sort();           
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        listbox_name.ItemsSource = list;
        grid1.Visibility = Visibility.Hidden;
    }


    private void button1_Click(object sender, RoutedEventArgs e)
    {
        grid1.Visibility = Visibility.Visible;
    }
  

Но при нажатии кнопки я не могу видеть списки с отображаемым списком. Пожалуйста, подскажите мне, где я ошибаюсь. Спасибо!

Комментарии:

1. почему вы используете так много панелей стека для отображения заголовков… Просто используйте ListView и используйте GridView внутри него и создайте столбцы GridView….

2. привет,@adcool2007 я новичок, поэтому не знаю, как поступить. попробую и ваш метод, спасибо!

Ответ №1:

Причина в том, что ваш stackPanel находится в Grid.Col="0" , и он очень маленький. Но ListBox находится внутри вашего stackPanel . У него есть запас, и он уменьшается. Вы не можете видеть свой listBox .

введите описание изображения здесь

Если вы сделаете что-то подобное:

 <StackPanel Margin="0,0,0,-279">
            <ListBox Name="listbox_name" Margin="1,30" Height="276" />
        </StackPanel>
  

вы увидите свой список, и он будет работать.

ПРИМЕЧАНИЕ: этот код является только примером. Вам нужно сделать лучший макет для вашего окна.

Вот как я сделал переключение окна:

 <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="678" Loaded="Window_Loaded">
    <Grid Name="grid1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="130"></ColumnDefinition>
            <ColumnDefinition Width="380"></ColumnDefinition>
            <ColumnDefinition Width="146"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="30"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>

        <TextBlock Text="File Name"  Grid.Row="0" Grid.Column="0" Margin="5" />
        <TextBlock Text="File Path"  Grid.Row="0" Grid.Column="1" Margin="5" />
        <TextBlock Text="File Size" Grid.Row="0" Grid.Column="2" Margin="5" />

        <ListBox Name="listbox_name" Grid.Row="1" Grid.Column="0" BorderBrush="Black" />
        <ListBox Name="listbox_path" Grid.Row="1" Grid.Column="1" BorderBrush="Black" />
        <ListBox Name="listbox_size" Grid.Row="1" Grid.Column="2" BorderBrush="Black" />
    </Grid>
</Window>
  

введите описание изображения здесь

Комментарии:

1. Привет, @sergey: Спасибо, это отлично работает! 🙂 но как насчет двух других? Как я могу их отобразить? Как и во всех 3 вместе?

2. Привет, @sergey: да, это именно то, что мне было нужно, спасибо! 🙂 У меня есть расширитель, как мне сделать сетку видимой (и изменить размер окна в соответствии с сеткой) при расширении расширителя? Огромное спасибо!

3. Но в этом случае пространство сетки отображается, даже если расширитель не расширен. Как мне увеличить размер окна при нажатии на расширитель?

4. Хммм. теперь я задал высоту моего окна = «181» Width =»Auto» SizeToContent=»WidthAndHeight». Моя кнопка и расширитель находятся за пределами grid1. Когда я разворачиваю расширитель, размер окна увеличивается, но сетка отображается поверх кнопки и расширителя. Как я могу этого избежать? Спасибо!

Ответ №2:

     <ListView Name="list"
              Grid.Row="1" 
              ItemsSource={Binding Path=Files}                
              >
    <ListView.View>        
     <GridView>
        <GridViewColumn Header="Name">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button>
                     <TextBlock Text="{BindingPath=Name}"/>                            
                    </Button>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
        <GridViewColumn Header="Size">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button>
                     <TextBlock Text="{BindingPath=Size}"/>                            
                    </Button>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
        <GridViewColumn Header="Path">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <Button>
                     <TextBlock Text="{BindingPath=Path}"/>                            
                    </Button>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>
     </ListView.View>  
    </ListView>
  

Моя ваша ViewModel будет

 public class FileListViewModel : INotifyPropertyChanged
{
    /// <summary>
    /// 
    /// </summary>
    public ObservableCollection<Fileinfo> Files{ get; set; }

    private Fileinfo selectedFile;

    public Fileinfo SelectedFile
    {
        get { return selectedFile; }
        set
        {
            selectedFile= value;
            InvokePropertyChanged(new PropertyChangedEventArgs("SelectedFile"));
        }
    }

    public PersonListViewModel()
    {
                //Loading List
                   Files= new ObservableCollection<Fileinfo>()
              {    //This is temp list you modify accordinh to you logic
                                   new FileInfo{Name = "File32"},
                                   new FileInfo{Name = "File33"},
                                   new FileInfo{Name = "File373"},
                                   new FileInfo{Name = "File393"},
                                   new FileInfo{Name = "File345"},
                                   new FileInfo{Name = "File375"},
                                   new FileInfo{Name = "File395"},
                                   new FileInfo{Name = "File387"},
                                   new FileInfo{Name = "File387"}
                               };
    }

    #region Implementation of INotifyPropertyChanged

    /// <summary>
    /// 
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="e"></param>
    public void InvokePropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, e);
    }

    #endregion
}
  

Ваша модель должна быть похожа

 public class FileinFo: INotifyPropertyChanged
{
    private string size;
    public event PropertyChangedEventHandler PropertyChanged;
    private string name;
    private bool isSelected;

    public string Size
    {
        get { return size; }
        set
        {
            size= value;
            InvokePropertyChanged(new PropertyChangedEventArgs("size"));
        }
    }

    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            InvokePropertyChanged(new PropertyChangedEventArgs("Name"));
        }
    }



    public bool IsSelected
    {
        get { return isSelected; }
        set
        {
            isSelected = value;
            InvokePropertyChanged(new PropertyChangedEventArgs("IsSelected"));
        }
    }

    public void InvokePropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }
}  
  

Вам нужно установить datacontext вашего представления в ViewModel

итак, допустим, ваше представление называется FileListView.xaml

Затем в коде за конструктором вы можете написать

 this.DataContext= new FileListViewModel();
  

Комментарии:

1. Привет, adcool, я знаю, что опаздываю, но я пробую метод, который вы предложили, поскольку мои требования так говорят. Я не уверен, возможно ли это, но есть ли способ в listview, чтобы я мог отобразить в нем arraylist? Нужна ли мне привязка к классу? Спасибо!

2. @user877852 — ваш список массивов содержит объекты того же типа. затем просто используйте ItemsSource= {Путь привязки=ListOfObjects}…. Также, если Объекты одного и того же типа… использовать общий список<>

3. привет @adcool, извини, но я новичок в этом. У меня есть три списка массивов. Я помещаю каждый из них под разные объекты (имя, путь и размер) и связываю их с помощью <ListBox ItemsSource=»{Путь привязки= name}» IsSynchronizedWithCurrentItem=»True»/> Я все еще не получаю правильного ответа. как я могу продолжить? Спасибо!