【问题标题】:How to apply wpf data binding on the fly at runtime如何在运行时动态应用 wpf 数据绑定
【发布时间】:2015-03-25 15:17:55
【问题描述】:

我一直致力于在运行时生成 WPF GUI 的任务。运行时生成的 GUI 被另一个 wpf 应用程序使用。模板生成器应用程序允许使用 XAMLWriter 创建 GUI 并将其保存为 xml(xaml 实际上是 xml)。消费者应用程序使用 XAMLReader 在 GUI 上添加模板。现在我想要在生成的模板中的控件之间进行某种绑定。

要求:第一个 Datepicker 上的日期 = 2015/01/02 和文本框 Text = 1 然后第二个 datepicker 上的日期必须是 2015/01/03。如果文本框文本 = -1,则第二个日期选择器上的日期必须为 2015/01/01。

我如何在运行时实现这一点。没有什么需要硬编码,因为生成的模板是从另一个应用程序生成的。我们在控件的 Tag 属性上有一些特定的值,这些值指示我们涉及哪些三个控件,哪个日期选择器是源,哪个日期选择器是目标以及需要使用哪个文本框文本。

是否可以使用动态数据绑定?或者如何做到这一点

【问题讨论】:

  • 这听起来像是可以通过数据触发器完全处理的事情,如果您提前知道值并且您所做的只是在它们之间切换。
  • 您在生成的 XAML 的开头使用 ObjectDataProvider 吗?什么类型的对象使用该 Datepicker、DataTemplate 或 XAML 的网格?是否有更多的 DataRow 应该绑定或只是分离的数据?您应该更具体地查看您发现的问题是什么。
  • 首先,如果后面没有代码,那么一个简单的Load就足够了System.Windows.Application.LoadComponent(this, resourceLocater); 查看自动生成的示例 i.g.cs 了解更多详细信息。如果后面有代码(在部分类中),那么它有点难:生成一个部分 C# 类,就像自动生成 i.g.cs 文件一样(加载指令在里面)。 My answer bello can be used if no codebehind

标签: c# wpf xaml data-binding datepicker


【解决方案1】:

=> 将您的 Xml 文件重命名为 Xaml

<UserControl ...>
<Grid>
    <StackPanel Background="Aqua">
    <TextBlock Text="{Binding Path=Label}" Width="200" Height="40"/>
    </StackPanel>
</Grid>

=> 这是你将与代码隐藏合并的类

public class XamlLoadedType:UserControl, IComponentConnector
{
    private bool _contentLoaded; 
    public void InitializeComponent() {
        if (_contentLoaded) {
            return;
        }
        _contentLoaded = true;
        var resourceLocater = new System.Uri(_uri, System.UriKind.Relative);            
        Application.LoadComponent(this, resourceLocater);
    }

    void IComponentConnector.Connect(int connectionId, object target) {
        this._contentLoaded = true;
    }

    string _uri ;
    public XamlLoadedType(string uri)
    {
        _uri = uri;
        InitializeComponent();
    }   
}

=> 主窗口及其视图模型:

<Window ...>
<Grid>
    <StackPanel>
        <Button Command="{Binding LoadCommand}" Width="100" Height="50">Load</Button>
    </StackPanel>
    <StackPanel Grid.Row="1">
        <ContentControl Content="{Binding LoadedContent}"/>
    </StackPanel>
</Grid>

public class MainViewModel:INotifyPropertyChanged
{
    public ICommand LoadCommand { get; set; }
    object _loadedContent;
    public object LoadedContent
    {
        get { return _loadedContent; }
        set {
            SetField(ref _loadedContent, value, "LoadedContent");
        }

    }
    public MainViewModel()
    {
        LoadCommand = new RelayCommand(Load, ()=>true);
    }

    private void Load()
    {
        var xamlLoaded = new XamlLoadedType("/WPFApplication1;component/XamlToLoad.xml.xaml");
        xamlLoaded.DataContext = new { Label = "HeyDude" };
        LoadedContent = xamlLoaded;

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多