【问题标题】:XAML Binding to a FrameworkElement in a UserControlXAML 绑定到 UserControl 中的 FrameworkElement
【发布时间】:2014-07-02 23:09:57
【问题描述】:

我有一个自定义的用户控件(MyControl),它有几个属性(效果很好)。我想要一个新属性,让使用 UserControl 的页面“粘贴”一些内容直接显示在 UserControl 中 - 例如。一条路径。我努力了; ContentPresenter、ContentControl、StackPanel,没有运气……

MyControl.xaml

<ContentControl Grid.Column="0" Content="{Binding MyContent, ElementName=root}"></ContentControl>

MyControl.xaml.cs

public object MyContent
{
  get { return (object)GetValue(MyContentProperty); }
  set { SetValue(MyContentProperty, value); }
}

public static readonly DependencyProperty MyContentProperty =
  DependencyProperty.Register("MyContent", typeof(object), typeof(MyControl), new PropertyMetadata(null));

SomePage.xml

<mycontrols:MyControl x:Name="FavoritesButton">
  <mycontrols:MyControl.MyContent>
    <Path Data="M1540.22,2082.07L1546.95,2102.78 1568.73,2102.78 1551.11,2115.58 1557.84,2136.29 1540.22,2123.49 1522.6,2136.29 1529.33,2115.58 1511.71,2102.78 1533.49,2102.78 1540.22,2082.07z" Stretch="Uniform" Fill="#FFFFFFFF" Width="50" Height="50" Margin="30"></Path>
  </mycontrols:MyControl.MyContent>
</mycontrols:MyControl>

【问题讨论】:

    标签: c# xaml binding user-controls dependencyobject


    【解决方案1】:

    我有以下效果非常好。 (虽然这有点违背 MVVM 的原则......我仍然喜欢在主窗口的单个框架区域中动态处理我的用户控件)

    我的 MainWindow.xaml:

    <!-- Main Frame -->
    <Grid Grid.Column="1" Margin="10" Name="MainWindowFrameContent">
       <ItemsControl ItemsSource="{Binding Path=MainWindowFrameContent}" >
    
          <!-- This controls the height automatically of the user control -->
          <ItemsControl.ItemsPanel>
             <ItemsPanelTemplate>
                <UniformGrid Columns="1" IsItemsHost="True"/>
             </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
       </ItemsControl>
    </Grid>
    

    我的 MainViewModel.cs:

    using System;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Input;
    using myProject.View;
    using myProject.Models;
    
    namespace myProject.ViewModel
    {
        public class MainViewModel : ObservableObject
        {
            public MainViewModel() { }
    
            // This handles adding framework (UI) elements to the main window frame
            ObservableCollection<FrameworkElement> _MainWindowFrameContent = new ObservableCollection<FrameworkElement>();
            public ObservableCollection<FrameworkElement> MainWindowFrameContent
            {
                get { return _MainWindowFrameContent; }
                set { _MainWindowFrameContent = value; RaisePropertyChangedEvent("MainWindowFrameContent"); }
            }
        }
    }
    

    MainViewModel.cs 是一个“公共类 MainViewModel : ObservableObject”。这允许我实现“RaisePropertyChangedEvent”,以便当我更改“MainWindowFrameContent”的值时绑定将成功更新。

    我的 ObservableObject.cs:

    using System.ComponentModel;
    
    namespace myProject.ViewModel
    {
        public class ObservableObject : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void RaisePropertyChangedEvent(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    然后,当我想向 MainWindowFrameContent 添加项目时,我只需在 MainViewModel.cs 中执行以下操作:

    void _AddNewUserControl()
    {
        myUserControl hControl = new myUserControl();
        MainWindowFrameContent.Clear(); // Clear the frame before displaying new content
        MainWindowFrameContent.Add(hControl);
    }
    

    然后,您可以根据需要创建任意数量的用户控件。您要显示的每个命令都可以在 VM 中具有自己的 void _AddNewUserControl 类型方法,并将显示到主窗口。同样,它有点与 MVVM 框架相反,但它从代码库中保持了这一点。

    【讨论】:

    • 另外,我的 MainWindow 数据上下文设置为 MainViewModel 的单个实例(在主窗口的构造函数中完成):
    【解决方案2】:

    我得到了它的工作......解决方案如下:

    MyControl.xaml

    <ContentControl Content="{Binding Shape, ElementName=root}" />
    

    MyControl.xaml.cs

    public Shape Shape
    {
        get { return (Shape)GetValue(ShapeProperty); }
        set { SetValue(ShapeProperty, value); }
    }
    
    public static readonly DependencyProperty ShapeProperty =
            DependencyProperty.Register("Shape", typeof(Shape), typeof(MyControl), new PropertyMetadata(null));
    

    SomePage.xml

    <mycontrols:MyControl>
        <mycontrols:MyControl.Shape>
            <Path Data="M1540.22,2082.07L1546.95,2102.78 1568.73,2102.78 1551.11,2115.58 1557.84,2136.29 1540.22,2123.49 1522.6,2136.29 1529.33,2115.58 1511.71,2102.78 1533.49,2102.78 1540.22,2082.07z" Style="{StaticResource PathStyle}" />
        </mycontrols:MyControl.Shape>
    </mycontrols:MyControl>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多