WPF Binding 2 Columns to ListView

拜拜、爱过 提交于 2019-12-13 09:39:29

问题


XAML:

<ListBox x:Name="MyTitleBox" ItemsSource="{Binding}"/>
<ListBox x:Name="MyInfoBox" ItemsSource="{Binding}"/>

In C#:

 MyTitleBox.ItemsSource = new List<string>(new string[] {"ID:", "Info:", "More Info:"});
 MyInfoBox.ItemsSource = new ObservableCollection<string>(MyMainInfo.ToString().Split(',').ToList<string>());

I currently have 2 list boxes next to each other because I need to handle their ItemsSource programmatically.

I know there must be a better way to merge the two. Essentially the list box "on the left" is the titles like ID: and the list box "on the right" is the information.

I thought I could do something like MyTitleBox.Columns.Add like I've seen but it won't let me do .Columns. I'm using .NET 4.


回答1:


Here is an example with a more MVVM approach:

Domain (The type of items you want to put in your list):

public class Movie : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _title;

    public string Title
    {
        get { return _title; }
        set
        {
            if (_title != value)
            {
                _title = value;

                RaisePropertyChanged("Title");
            }                
        }
    }

    private string _info;

    public string Info
    {
        get { return _info; }
        set
        {
            if (_info != value)
            {
                _info = value;

                RaisePropertyChanged("Info");
            }                
        }
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<Movie> _movies;

    /// <summary>
    /// Collection of movies.
    /// </summary>
    public ObservableCollection<Movie> Movies
    {
        get { return _movies; }
        set
        {
            if (_movies != value)
            {
                _movies = value;

                RaisePropertyChanged("Movies");
            }
        }
    }

    /// <summary>
    /// Constructor
    /// </summary>
    public MyViewModel()
    {
        Movies = new ObservableCollection<Movie>();

        Movies.Add(new Movie() { Title = "Gravity", Info = "Gravity is about..." });
        Movies.Add(new Movie() { Title = "Avatar", Info = "Avatar is about..." });
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAML:

<Window x:Class="StackOverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:StackOverflow"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListBox ItemsSource="{Binding Movies}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock>
                        <Run Text="{Binding Title}" /><Run Text=" - " /><Run Text="{Binding Info}" />
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <Button Grid.Row="1" Content="Click To Change Info" Margin="5" Click="Button_Click" />
    </Grid>
</Window>

Code Behind:

public partial class MainWindow : Window
{
    public MyViewModel ViewModel { get; private set; }

    public MainWindow()
    {
        InitializeComponent();

        ViewModel = new MyViewModel();

        DataContext = ViewModel;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Movie movie = ViewModel.Movies.FirstOrDefault();

        if (movie != null)
        {
            movie.Info = "This is the new information";
        } 
    }
}

Implementing INotifyPropertyChanged allows the code to notify the UI when something changes.

If you test this code out you will see that clicking the button updates the info for the first movie, and this changed is immediately reflected in the UI. (Normally you would use a convention like Commands for handling the button click, but for simplicity I did it this way)

Let me know if you have any questions.



来源:https://stackoverflow.com/questions/21683413/wpf-binding-2-columns-to-listview

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!