如何为UserControl绑定其他DataContext?

时间:2019-01-24 14:10:37

标签: c# .net wpf mvvm

所以我有一个这样的应用程序。 我的MainView.xaml

<ItemsControl ItemsSource="{Binding CardViewModel.Users}"
                          dd:DragDrop.IsDragSource="True"
                          dd:DragDrop.IsDropTarget="True"
                          dd:DragDrop.UseDefaultEffectDataTemplate="True">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <controls:UserCard/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

            </ItemsControl>

还有ViewModel

class BaseViewModel : ObservableObject
{
    public CardViewModel CardViewModel { get; set; } = new CardViewModel();
}

这很好用,它在ItemsControl中显示两个UserCards是我的UserControl,这正是它应该做的事,并且还将Text属性绑定到需要的内容。

 <Grid Style="{StaticResource UserCardStyle}">
        <Grid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Edit"/>
                <MenuItem Header="Remove"
                          Command="{Binding BaseViewModel.CardViewModel.command}"/>
            </ContextMenu>
        </Grid.ContextMenu>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="75"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>



        <Grid Width="75"
                  HorizontalAlignment="Left"
                  Column="0">
            <Ellipse Width="50"
                         Height="50"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Center"
                         Margin="10">
                <Ellipse.Fill>
                    <ImageBrush ImageSource="{Binding Avatar}"/>
                </Ellipse.Fill>
            </Ellipse>
        </Grid>

        <Grid Column="1">
            <TextBlock Text="{Binding Description}"

                           TextWrapping="Wrap"
                           Width="180"
                           VerticalAlignment="Top"
                           Margin="10"
                           FontFamily="Consolas"/>


            <TextBlock Width="100"
                           Height="20"
                           VerticalAlignment="Bottom"
                           HorizontalAlignment="Right"
                           Margin="5"
                           Text="{Binding Name}"
                           FontFamily="Consolas"/>
            <TextBlock Width="100"
                           Height="20"
                           VerticalAlignment="Bottom"
                           HorizontalAlignment="Left"
                           Text="{Binding Id}"
                           FontFamily="Consolas"/>
        </Grid>
    </Grid>

但是我想添加一个DataContext,如您在顶部看到的那样,但是我不知道如何将UserControl的DataContext绑定到其他对象,以便为ContextMenu MenuItems

创建命令

我确实设置了可以在ViewModel上使用的RelayCommand,因为我在那里正确设置了DataContext。

现在,UserCard数据上下文在MainWindow视图中从其父级继承,这使其属性的DataContext都来自User

public class User : ObservableObject
    {
        public ImageSource Avatar { get; set; } 
        public string Description { get; set; }
        public int Id { get; set; }
    }

我希望能够为该特定控件创建ViewModel并向其添加命令,或者我可以将其绑定到CardViewModel并仍显示Users集合中的数据< / p>

public CardViewModel()
{
    /*
     * Commands
     */
    command = new RelayCommand(o => LoadImage(), o => true);
    AddUser = new RelayCommand(u => DisplayUserBuilder(), u => true);

    Users = new ObservableCollection<User>();

    Users.Add(new User
    {
        Name = "User",
        Description = "A description",
        Id = 0
    });
    Users.Add(new User
    {
        Name = "User1",
        Description = "Super nice description",
        Id = 1

    });

如果我像这样在CodeBehind中设置DataContext,该命令可以正常运行,但是我看不到任何文本

public partial class UserCard : UserControl
    {
        public UserCard()
        {
            InitializeComponent();
            this.DataContext = new BaseViewModel();
        }
    }

2 个答案:

答案 0 :(得分:1)

我相信您需要这样的东西:

<Grid.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Edit"/>
            <MenuItem Header="Remove"
                      Command="{Binding DataContext.CardViewModel.command, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type MainView}}"/>
        </ContextMenu>
    </Grid.ContextMenu>

答案 1 :(得分:0)

这就是我最终要做的,添加对ViewModel的引用,然后进行设置。

<Grid.ContextMenu>
            <ContextMenu >
                <ContextMenu.DataContext>
                    <dad:BaseViewModel/>
                </ContextMenu.DataContext>

                <MenuItem Header="Edit"/>
                <MenuItem Header="Remove"
                          Command="{Binding CardViewModel.command}"/>
            </ContextMenu>
        </Grid.ContextMenu>

如果某人知道做同一件事的“更好”或“更清洁”的方式,请告诉我,因为我正试图以开发人员的身份进行开发,所以没有双关语。