如何在运行时动态应用WPF数据绑定

3
我一直在处理一个任务,其中WPF GUI是在运行时生成的。运行时生成的GUI由另一个WPF应用程序使用。模板生成器应用程序允许创建GUI并将其保存为xml(XAML实际上是xml),使用XAMLWriter。使用XAMLReader的消费者应用程序将模板添加到GUI中。现在我想在生成的模板控件之间进行绑定。

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

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

是否可以使用动态数据绑定?或者如何完成这个任务?


2
如何提出一个好问题? - user585968
如果您提前知道值并且您所做的只是在它们之间切换,那么这似乎完全可以使用数据触发器来处理。 - Johnathon Sullinger
你在生成的XAML开头使用ObjectDataProvider吗?那个Datepicker使用什么类型的对象,是DataTemplate还是XAML的Grid?有更多的DataRow需要绑定还是只是单独的数据? 你应该更具体地看到你发现的问题是什么。 - Jettero
首先,如果没有任何后台代码,则简单的Load就足够了。System.Windows.Application.LoadComponent(this, resourceLocater); 可以查看自动生成的 i.g.cs 示例获取更多详细信息。 如果有后台代码(在部分类中),那么就有点难了:以与“i.g.cs”文件自动生成相同的方式生成一个部分类的C#类(加载指令在内部)。如果没有codebehind,可以使用我的回答 bello。 - adPartage
1个回答

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;

    }
}

Voilà

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接