简体   繁体   English

将控件绑定到不同的DataContext

[英]Binding controls to different DataContexts

I have a situation where I want to bind a ListBox with a List of class items and SolidColorBrush property to foreground of a TextBlock that is part of the ListBox itself. 我遇到一种情况,我想将具有类items列表和SolidColorBrush属性的ListBox绑定到作为ListBox本身一部分的TextBlock foreground

Data of ListBox comes from the class User and SolidColorBrush property from the class MyColors However, I am not able to set DataContexts for both of them at the same time. ListBox数据来自MyColors类的UserSolidColorBrush属性。但是,我无法同时为它们两个设置DataContexts Setting DataContext twice overrides the first one and the ListBox is not populated. 设置DataContext两次将覆盖第一个,并且不会填充ListBox Please help! 请帮忙!

public Page1()
    {
        this.DataContext = GetUsers();
        this.DataContext = textcolor; // <-overrides the previous DataContext
    }

Code Behind: 背后的代码:

xaml: xaml:

<Grid HorizontalAlignment="Left" Height="650" Margin="0,38,0,0" Grid.RowSpan="2" VerticalAlignment="Top" Width="480">
        <ListBox x:Name="lstBani1" ItemsSource="{Binding}" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock x:Name="tb1" Text="{Binding string1}" Foreground="{Binding Path=Brush1, Mode=OneWay}" Width="480"/>
                        <TextBlock x:Name="tb2" Text="{Binding string2}" Width="480"/>
                        <TextBlock x:Name="tb3" Text="{Binding string3}" Width="480"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>

cs: CS:

 public partial class Page1 : PhoneApplicationPage
    {
        public Page1()
        {
            InitializeComponent();          
            MyColors textcolor = new MyColors();
            textcolor.Brush1 = new SolidColorBrush(Colors.Red);

            this.DataContext = GetUsers();
            this.DataContext = textcolor; // <-overrides the previous DataContext
        }
        private List<User> GetUsers() {...}
    }   
    public class User
        {
            public string string1 { get; set; }
            public string string2 { get; set; }
            public string string3 { get; set; }
        } 


public class MyColors : INotifyPropertyChanged
    {
        private SolidColorBrush _Brush1;
        public event PropertyChangedEventHandler PropertyChanged;

        public SolidColorBrush Brush1
        {
            get { return _Brush1; }
            set
            {
                _Brush1 = value;
                NotifyPropertyChanged("Brush1");
            }
        }

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

there are a quite a few ways to achieve this. 有很多方法可以实现这一目标。

Though as my time at the desk here is limited tonight I'll do it in a bit of a messy ViewModel type way. 尽管由于今晚我在办公桌上的时间有限,所以我将以一种杂乱的ViewModel类型的方式进行操作。

Rather than trying to pass two objects into the datacontext. 而不是尝试将两个对象传递到数据上下文中。 What I would suggest is creating what is commonly called a View Model. 我建议创建通常称为“视图模型”的视图。 If you aren't familiar with the MVVM pattern, there's quite a lot on-line to read up on. 如果您不熟悉MVVM模式,则可以在线阅读很多内容。 It's a large pattern however and I only use small parts of it for most of my work. 但是,这是一个很大的模式,我在大部分工作中只使用其中的一小部分。

Based on your code from above, I have added a class which looks something like the following. 根据上面的代码,我添加了一个类似于以下内容的类。

public class AViewModel
{
    public List<User> Users { get; set; }
    public MyColors Colours { get; set; }
}

This is the object I'm going to pass as the data context, and newing up the list of Users and MyColors before passing it to the datacontext. 这是我要作为数据上下文传递的对象,并在将用户和MyColors列表传递给数据上下文之前对其进行了更新。

Now, for the list box I can do something like this... 现在,对于列表框,我可以执行以下操作...

<ListBox ItemsSource="{Binding Users}" Foreground="{Binding Colours.Brush1}">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock x:Name="tb1" Text="{Binding string1}" Foreground="{Binding Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}" Width="480"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>

    </ListBox>

I bind the foreground of the Listbox to the colour, and then pass that using relative source on the TextBlocks's Foreground DP 我将列表框的前景绑定到颜色,然后在TextBlocks的前景DP上使用相对源传递它

I did this with a Windows UNI app and I have red text showing in my items. 我是使用Windows UNI应用程序执行此操作的,我的项目中显示红色文字。 However, there are numerous things which could override this colour. 但是,有很多事情可以覆盖这种颜色。 And we could go on all night talking about that. 我们可以整夜谈论这个。

Hope this is of some help to you. 希望这对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM