【问题标题】:Rebuild statusbar on the fly with databinding使用数据绑定即时重建状态栏
【发布时间】:2013-06-20 13:15:15
【问题描述】:

我正在构建一个插件系统,其中每个插件都有自己的状态栏,包含不同的区域。所以插件#1 可以有一个带有 2 x 200 像素区域的状态栏,而插件 #2 可以只有一个 400 像素区域。

我在WPF/MVVM 和我的应用程序视图模型中构建它,当我在插件之间切换时,插件的StatusBar 会被加载。

我有一个可观察的状态栏集合,可以加载到:

ObservableCollection<StatusBar> StatusBars 
{ 
    get;
    set;
}

然后我有一个函数只是检索该插件的状态栏集合。

被加载的类看起来像这样:

public class StatusBar : ObservableObject
{
    public string Name { get; set; }
    public int Width { get; set; }
    public StatusBarAreaType Type { get; set; }

    string _message;

    public string Message
    {
        get
        {
            return _message;
        }

        set
        {
            if (_message != value)
            {
                _message = value;
                OnPropertyChanged();
            }
        }
    }
}

我的问题是我无法让 XAML 支持我加载集合并将每个 StatusBar 显示为自己的区域。我尝试的简化版本如下所示:

<StatusBar VerticalAlignment="Bottom" Height="25" ItemsSource="{Binding StatusBars}" ItemTemplate="{DynamicResource StatusBarTemplate}">
    <StatusBar.Resources>
        <DataTemplate x:Key="StatusBarTemplate">
            <TextBlock Text="{Binding Message}"></TextBlock>
        </DataTemplate>
    </StatusBar.Resources>
</StatusBar>

(我已经尝试过StatusBarItem 的东西,ItemsControl 模板,在内部使用网格等等)

如何实现我的目标,即拥有一个由基于 StatusBar 类的不同区域组成的 StatusBar

【问题讨论】:

  • 这看起来像是模板选择器类型的问题。您是否考虑过使用模板选择器?
  • 我打算在稍后阶段添加它,以便能够根据类型更改区域的内容。但由于我无法让这些地区开始工作,所以我还没有走那么远。你的意思是如何解决我的问题?
  • 为什么区域不工作?
  • 好吧,我目前还没有完成将 Itemssource 绑定到模型并让它生成东西的第一步,而且谷歌没有给我任何命中,有人正在对一个模型进行任何类型的绑定WPF 状态栏。所以如果你知道如何做第一步,请分享:)
  • 好吧,我开始明白这里了。 StatusBar 继承自 ItemsControl 所以你不需要是 items 而不是容器吗?

标签: c# wpf mvvm binding statusbar


【解决方案1】:

我现在实际上能够解决这个问题,这是我的 XAML:

<UserControl x:Class="MyCompany.View.StatusBarControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:viewModel="clr-namespace:MyCompany.ViewModel"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding StatusBar,Source={StaticResource Locator}}">
    <UserControl.Resources>
        <DataTemplate x:Key="SimpleTextDataTemplate">
            <StatusBarItem Width="{Binding Width}" Margin="0,5,0,0">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Message}"></TextBlock>
                </StackPanel>
            </StatusBarItem>
        </DataTemplate>

        <DataTemplate x:Key="ErrorDataTemplate">
            <StatusBarItem Width="{Binding Width}" Margin="0,5,0,0">
                <TextBlock Text="{Binding Message}"></TextBlock>
            </StatusBarItem>
        </DataTemplate>

        <DataTemplate x:Key="ProgressBarDataTemplate">
            <StatusBarItem Width="{Binding Width}" Margin="0,10,0,0">
                <ProgressBar Width="{Binding Width}" Height="{Binding ElementName=theStatusBar,Path=Height}" Value="{Binding Message}"></ProgressBar>
            </StatusBarItem>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>
        <StatusBar x:Name="theStatusBar" VerticalAlignment="Bottom" Background="#d0d2d6" Height="30"
                   ItemsSource="{Binding StatusBars}">
            <StatusBar.ItemTemplateSelector>
                <viewModel:StatusBarRegionSelector SimpleTextTemplate="{StaticResource SimpleTextDataTemplate}"
                                                   ErrorTemplate="{StaticResource ErrorDataTemplate}"
                                                   ProgressBarTemplate="{StaticResource ProgressBarDataTemplate}" />
            </StatusBar.ItemTemplateSelector>
        </StatusBar>
    </Grid>
</UserControl>

以及背后的代码:

public class StatusBarRegionSelector : DataTemplateSelector
    {
        public DataTemplate SimpleTextTemplate { get; set; }
        public DataTemplate ErrorTemplate { get; set; }
        public DataTemplate ProgressBarTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var statusBar = (StatusBar) item;

            if (statusBar != null)
                switch (statusBar.Type)
                {
                    case StatusBarAreaType.SimpleText:
                        return SimpleTextTemplate;
                        break;
                    case StatusBarAreaType.Error:
                        return ErrorTemplate;
                        break;
                    case StatusBarAreaType.ProgressBar:
                        return ProgressBarTemplate;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

            return SimpleTextTemplate;
        }
    }

现在唯一的问题是在每个项目之间添加一个分隔符,现在只是添加一个分隔符由于某种原因不起作用,无论我放在哪里都不会显示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多