代码之家  ›  专栏  ›  技术社区  ›  Mark Denom

如何为用户控件绑定不同的数据上下文?

  •  1
  • Mark Denom  · 技术社区  · 6 年前

    所以我有一个这样设置的应用程序。 我的主视图.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>
    

    和视图模型

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

    很好,显示两个 UserCards 这是我在itemscontrol中的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 datacontext在mainwindow视图中继承自其父级,从而使其成为属性的datacontext的来源 User

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

    我希望能够为那个特定控件创建一个VIEW模型,并将命令添加到那个控件中,或者这样我就可以将它绑定到 CardViewModel 仍然显示来自 Users 收集

    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
    
        });
    

    如果在这样的代码后面设置DATACONTRONT,命令工作正常,但我看不到任何文本。

    public partial class UserCard : UserControl
        {
            public UserCard()
            {
                InitializeComponent();
                this.DataContext = new BaseViewModel();
            }
        }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Marcin Topolewski    6 年前

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

    <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>
    
        2
  •  0
  •   Mark Denom    6 年前

    这就是我最后做的,添加对viewmodel的引用,然后设置它。

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

    如果有人知道一个“更好”或“更干净”的方式做同样的事情,请让我知道,因为我正在努力发展作为一个开发人员,没有双关语的意图。