Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
202 views
in Technique[技术] by (71.8m points)

c# - WPF Binding 2 Columns to ListView

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...