【问题标题】:Binding XAML Controls to a List将 XAML 控件绑定到列表
【发布时间】:2015-09-06 11:47:08
【问题描述】:

我正在开发一个 Windows 商店应用程序。我所做的是,我创建了一个类,ContactBook,其中包含一些属性、字段和构造函数。然后我列了一个清单

List<ContactBook>

我将课程添加到的位置。我想将几个文本块和一个图像绑定到列表中,以便每个显示它们各自的值。到目前为止,我已经创建了以下代码:

班级

public class ContactBook
    {
        #region _Fields

        private string _Name;
        private string _Surname;
        private string _Number;
        private string _ImagePath;

        #endregion

        #region Constructors

        public ContactBook(string name, string surname, string number, string imagePath)
        {
            ImagePath = imagePath;
            Name = name;
            Surname = surname;
            Number = number;
        }

        public ContactBook()
        {
            ImagePath = null;
            Name = null;
            Surname = null;
            Number = null;
        }

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                this._Name = value;
            }
        }

        public string Surname
        {
            get
            {
                return _Surname;
            }
            set
            {
                this._Surname = value;
            }
        }

        public string Number
        {
            get
            {
                return _Number;
            }
            set
            {
                this._Number = value;
            }
        }

        public string ImagePath
        {
            get
            {
                return _ImagePath;
            }
            set
            {
                this._ImagePath = value;
            }
        }

        #endregion

    }

XAML

<Page
x:Class="Summative_LU08.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Summative_LU08"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:myNS="using:Summative_LU08"
mc:Ignorable="d" Loaded="Page_Loaded">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Contacts" VerticalAlignment="Top" FontFamily="Segoe UI" FontSize="72"/>
        <TextBlock HorizontalAlignment="Left" Height="7" Margin="1452,740,-101,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="15"/>
        <TextBlock x:Name="Name_Text" Text="Name: " FontSize="20" Margin="180,124,1112,620"/>
        <TextBlock x:Name="theName" Text="{Binding }" FontSize="20" Margin="180,153,939,585"/>
        <TextBlock x:Name="Surname" Text="Surname: " FontSize="20" Margin="180,208,1087,529"/>
        <TextBlock x:Name="theSurname" Text="" FontSize="20" Margin="180,244,1079,496"/>
        <TextBlock x:Name="thenumber" Text="" FontSize="20" Margin="10,308,1246,426"/>
        <Image Width="160" HorizontalAlignment="Left" Margin="10,124,0,496"/>

        <Image Width="160" HorizontalAlignment="Left" Margin="10,369,0,251"/>
        <TextBlock x:Name="ContactNumber" Text="Contact Number:" Width="160" HorizontalAlignment="Left" FontSize="20" Height="31" FontStyle="Normal" FontFamily="Segoe UI" Margin="10,277,0,460"/>
        <TextBlock x:Name="Name_2" Text="Name: " FontSize="20" Margin="182,369,1110,375"/>
        <TextBlock x:Name="theName_2" Text="" FontSize="20" Margin="182,398,1127,337"/>
        <TextBlock x:Name="Surname_2" Text="Surname: " FontSize="20" Margin="182,453,1085,284"/>
        <TextBlock x:Name="theSurname_2" Text="" FontSize="20" Margin="182,489,1077,251"/>
        <TextBlock x:Name="ContactNumber_2" Text="Contact Number:" Width="160" HorizontalAlignment="Left" FontSize="20" Height="31" FontStyle="Normal" FontFamily="Segoe UI" Margin="10,522,0,215"/>
        <TextBlock x:Name="thenumber_Copy" Text="" FontSize="20" Margin="10,553,1246,181"/>
    </Grid>
</Page>

代码隐藏

private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            List<ContactBook> contactsBook = new List<ContactBook>();
            ContactBook contactBook_1 = new ContactBook();
            ContactBook contactBook_2 = new ContactBook();


            contactBook_1.Name = "Jaco";
            contactBook_1.Surname = "Badenhorst";
            contactBook_1.Number = "0728568956";
            contactBook_1.ImagePath = "Assets\\Contact";

            contactBook_2.Name = "Dean";
            contactBook_2.Surname = "Lukas";
            contactBook_2.Number = "0825653565";
            contactBook_2.ImagePath = "Assets\\Contact";

            contactsBook.Add(contactBook_1);
            contactsBook.Add(contactBook_2);

            theName.SetBinding(contactsBook, contactsBook[0]);
        }

如何将文本块绑定到列表,以便theName 文本块显示名称等。 “the”前面的所有文本块名称只是标签,另一个将保存实际值。

【问题讨论】:

    标签: c# xaml windows-store-apps


    【解决方案1】:

    为了支持绑定,模型类应该实现 INotifyPropertyChanged - 这将触发数据更改的事件,因此控件知道它们需要重绘。

    要开始在页面上绑定,您首先需要查看页面的 DataContext(最常见的做法) - 定义控件获取数据的位置。然后为每个控件定义使用 {Binding } 注释的属性。在该绑定定义中,您可以添加诸如模式之类的行为,以使数据仅从模型流向控件或双向流向(控件中的更改随后存储在模型中)。

    对于更改集合,最好使用 ObservableCollection,因此集合中的更改也会触发集合控件中的更改(如 ListVIew)。

    这可能会有所帮助....

    将此类添加到您的解决方案中:

    /// <summary>
    /// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
    /// </summary>
    public abstract class BindableBase : INotifyPropertyChanged
    {
        /// <summary>
        /// Multicast event for property change notifications.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
    
        /// <summary>
        /// Checks if a property already matches a desired value.  Sets the property and
        /// notifies listeners only when necessary.
        /// </summary>
        /// <typeparam name="T">Type of the property.</typeparam>
        /// <param name="storage">Reference to a property with both getter and setter.</param>
        /// <param name="value">Desired value for the property.</param>
        /// <param name="propertyName">Name of the property used to notify listeners.  This
        /// value is optional and can be provided automatically when invoked from compilers that
        /// support CallerMemberName.</param>
        /// <returns>True if the value was changed, false if the existing value matched the
        /// desired value.</returns>
        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
        {
            if (Equals(storage, value)) return false;
    
            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }
    
        /// <summary>
        /// Notifies listeners that a property value has changed.
        /// </summary>
        /// <param name="propertyName">Name of the property used to notify listeners.  This
        /// value is optional and can be provided automatically when invoked from compilers
        /// that support <see cref="CallerMemberNameAttribute"/>.</param>
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var eventHandler = PropertyChanged;
            if (eventHandler != null)
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    让您的 ContactBook 类继承自此类:

    public class ContactBook : BindableBase
    

    用这个代替你当前的 getter 和 setter:

    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }
    

    您的页面代码应如下所示(简单解决方案):

        public sealed partial class MainPage : BasePage
        {
            public ObservableCollection<ContactBook> Books;
    
            public MainPage()
            {
                this.InitializeComponent();
                // In Windows 8 apps you must set the DataContext. So uncomment the next line in that case
                //DataContext = this;
                Loaded += MainWindow_Loaded;
            }
    
            private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                Books = new ObservableCollection<ContactBook>();
                // add code to read from a service, database, etce
            }
    }
    

    在 XAML 中,您可以添加一个 ListView 来显示所有项目:

    <ListView ItemsSource={Binding Books} />
    

    要显示一个项目的数据,您应该适当地设置上下文,例如在您的页面 CurrentBook 中有一个 ContactBook 类型的额外属性,用于指示当前选择。

    显示(和编辑)您可以使用的项目名称:

    <TextBox Text={Binding CurrentBook.Name, Mode=TwoWay} />
    

    研究 MVVM 对您来说是一个很好的研究项目 - 这是一种定义模型、视图并将两者连接在一起的方法。例如参见:http://www.mvvmlight.net/

    希望这能让你开始。

    马丁

    【讨论】:

    • 太棒了!非常感谢!!我一定会开始玩这个,非常感谢。
    猜你喜欢
    • 2012-10-21
    • 2012-02-12
    • 2013-03-29
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    相关资源
    最近更新 更多