如何将textblock.foreground绑定到变量? (WPF C#)

时间:2014-06-30 16:26:18

标签: c# wpf visual-studio-2013 textblock

所以我希望改变我的程序,以便我可以运行一个函数来检查并查看前景色是黑色还是银色。我希望将那些不可访问的字段变为灰色"。

我的表单目前看起来像: enter image description here

我希望"灰色" "无需维护"领域。但是我在尝试在数据模板中为字体前景定义绑定元素时遇到问题。

我尝试在后面的主窗口代码中定义一个IValueConverter类,到定义一个窗口密钥资源,但是我没有尝试过,但是我不能在一个数据模板中做到这一点。 textblock元素本身?

任何建议/帮助将不胜感激。谢谢!

XAML:     

<Grid Margin="0,0,2,0">

    <ListBox x:Name="allSites_LB" 
             HorizontalAlignment="Left" 
             Height="400" 
             Margin="20,60,0,0" 
             VerticalAlignment="Top" 
             Width="945"
             Loaded="allSites_LB_Loaded" 
             BorderThickness="1" SelectionChanged="allSites_LB_SelectionChanged"
             ScrollViewer.HorizontalScrollBarVisibility="Disabled"
             >
        <ListBox.ItemTemplate >
            <DataTemplate >
                <Border BorderBrush="Black" BorderThickness="0,0,0,1" Margin="-20,1,0,1" Padding="0,5,0,5" >
                    <Grid Margin="75,3" >
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="200" />
                            <ColumnDefinition Width="400" />
                            <ColumnDefinition Width="345" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding SiteNo}" Grid.Column="0" FontSize="16" />
                        <TextBlock Text="{Binding Address}" Grid.Column="1" FontSize="16" Margin="50,1" />
                        <TextBlock Text="{Binding MaintStatus}" Grid.Column="2" FontSize="16" />
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <Button x:Name="viewHistory_BTN" 
            Content="View History" 
            HorizontalAlignment="Left" 
            Height="52" 
            Margin="20,496,0,0" 
            VerticalAlignment="Top" 
            Width="172" FontSize="20"
            />

    <Button x:Name="startMaintenance_BTN" 
            Content="Start Maintenance"
            HorizontalAlignment="Left" 
            Height="52" 
            Margin="793,496,0,0" 
            VerticalAlignment="Top" 
            Width="172" FontSize="20"
            />
    <TextBox x:Name="Site_Address" 
             HorizontalAlignment="Left" 
             Height="21" 
             Margin="51,39,0,0" 
             TextWrapping="Wrap" 
             Text="Site Number" 
             VerticalAlignment="Top" 
             Width="75" 
             BorderBrush="White" 
             IsReadOnly="True" 
             IsEnabled="False"

             />
    <TextBox x:Name="Address_Title" 
             HorizontalAlignment="Left" 
             Height="21" 
             Margin="380,34,0,0" 
             TextWrapping="Wrap" 
             Text="Address" 
             VerticalAlignment="Top" 
             Width="75" 
             BorderBrush="White"
             IsReadOnly="True" 
             IsEnabled="False"

             />
    <TextBox x:Name="maint_Title" 
             HorizontalAlignment="Left" 
             Height="21" 
             Margin="699,34,0,0" 
             TextWrapping="Wrap" 
             Text="Maintenance Record" 
             VerticalAlignment="Top" 
             Width="117" 
             BorderBrush="White" 
             IsReadOnly="True" 
             IsEnabled="False"
             />

</Grid>

C#代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;



namespace SiteMaintenance
{

public partial class MainWindow : Window
{

    /**
     * CLASS VARIABLES
     * */
    private SqlConnection localdbConnection;        // Connection to Site Maintenance DB (LOCAL)
    private System.Data.DataSet allSitesResults;



    // MAIN THREAD
    public MainWindow()
    {
        InitializeComponent();

        // try to open SQL Connection
        try {
            localdbConnection = new SqlConnection(Properties.Settings.Default.localdb);
            localdbConnection.Open();
        } catch(Exception ex) {
           System.Windows.MessageBox.Show("local SQL connection unable to connect");
           return;
        }

        viewHistory_BTN.IsEnabled = false;
        startMaintenance_BTN.IsEnabled = false;
        startMaintenance_BTN.IsDefault = true;
    }

    /**
     * Load dataset into datagrid 
     * LAZY LOADING
     * */
    private void DataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        // init command object
        SqlCommand myCommand = new SqlCommand();
        myCommand.CommandText = "dbo.usp_GetSites";
        myCommand.CommandType = System.Data.CommandType.StoredProcedure;
        myCommand.Connection = localdbConnection;

        // init data adaptor
        SqlDataAdapter sites = new SqlDataAdapter();
        sites.SelectCommand = myCommand;

        //init DataSet
        allSitesResults = new System.Data.DataSet();

        sites.Fill(allSitesResults, "tblSites");

        int tableCount = allSitesResults.Tables.Count;

        System.Data.DataTable test = allSitesResults.Tables[0];

        int rowCount = test.Rows.Count;





    }

    private void sites_DG_CurrentCellChanged(object sender, EventArgs e)
    {
        String siteName = allSitesResults.Tables[0].Rows[0][1].ToString();

    }

    private void allSites_LB_Loaded(object sender, RoutedEventArgs e)
    {
        // init command object
        SqlCommand myCommand = new SqlCommand();
        myCommand.CommandText = "dbo.usp_GetSitesANDCompletedDate";
        myCommand.CommandType = System.Data.CommandType.StoredProcedure;
        myCommand.Connection = localdbConnection;

        // init data adaptor
        SqlDataAdapter sites = new SqlDataAdapter();
        sites.SelectCommand = myCommand;

        //init DataSet
        allSitesResults = new System.Data.DataSet();

        sites.Fill(allSitesResults, "tblSites");

        allSites_LB.ItemsSource = allSitesResults.Tables["tblSites"].DefaultView;

    }


    // do not allow selection of maintenance records that do not exist
    private void allSites_LB_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

        // grab the index
        int selectedIndex = allSites_LB.SelectedIndex;
        if (selectedIndex == -1) return;                //WITHOUT THIS CHECK, UN-SELECTION WILL CAUSE LOGIC FAILURE

        System.Data.DataRowView tempData = (System.Data.DataRowView)allSites_LB.Items[allSites_LB.SelectedIndex];

        // grab the completed date field
        String completedDate = tempData["CompletedDate"].ToString();
        String siteMaintID = tempData["SiteMaintID"].ToString();

        // remove selected index if completed date and site Maint ID is null
        if (siteMaintID != "" && completedDate == "")
        {
            startMaintenance_BTN.IsEnabled = true;
        }
        else 
        {
            allSites_LB.SelectedIndex = -1;
            startMaintenance_BTN.IsEnabled = false;
        }

    }


    private String maintRequired(object sender, SelectionChangedEventArgs e)
    {
        int selectedIndex = allSites_LB.SelectedIndex;
        if (selectedIndex < 0) return null;

        System.Data.DataRowView tempData = (System.Data.DataRowView)allSites_LB.Items[allSites_LB.SelectedIndex];

        // grab the completed date field
        String completedDate = tempData["CompletedDate"].ToString();
        String siteMaintID = tempData["SiteMaintID"].ToString();

        if (siteMaintID != "" && completedDate == "")
        {
            return "Maintenance Required";
        }
        else
        {
            return "No Maintenance";
        }
    }

}

}

3 个答案:

答案 0 :(得分:4)

将Foreground颜色绑定到一段数据时,通常有两种很好的方法供您选择。根据您的要求,不同的人会有不同的偏好。所以......这里都是!

第一种方法:带触发器的样式

这种方法基本上可以识别出特殊的&#39;满足某些条件时的行为。在这种情况下,当状态==&#34;无需维护&#34;

时,我们会将前景色更改为灰色
<Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Black" /> <!-- default value -->
    <Style.Triggers>
        <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}" Value="No Maintenance Required">
            <Setter Property="Foreground" Value="Gray" /> <!-- special behavior -->
        </DataTrigger>
    </Style.Triggers>
</Style>

在这种情况下,只需为TextBlock分配相应的Style属性。

第二种方法:使用IValueConverter

此方法创建自定义&#34; IValueConverter实现,将Text值转换为Color。从那里,我们直接绑定到我们的文本值,并确保转换器始终提供正确的颜色。

public class MaintenaceColorConverter : IValueConverter
{

    public Color NormalColor { get; set; }
    public Color NoMaintenanceRequiredColor { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value.ToString() == "No Maintenance Required")
            return NoMaintenanceRequiredColor;

        return NormalColor;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在您的XAML中:

<Window.Resources>
    <local:MaintenaceColorConverter x:Key="myColorConverter" NormalColor="Black" NoMaintenanceRequiredColor="Gray" />
</Window.Resources>

在TextBlock中:

<TextBlock Text="{Binding MaintStatus}" Foreground="{Binding MaintStatus, Converter={StaticResource myColorConverter}}" />

改进

使用这些方法中的任何一种,最好有MaintenanceStatus布尔值或枚举值,并将样式条件绑定到该值。使用字符串比较是个坏主意。那只是在乞求麻烦。这些示例使用了字符串比较,因为......嗯......这些都可以从您提供的示例代码中获得。

答案 1 :(得分:1)

比你要求的更多,但这是来自一些现有的代码

<Style TargetType="ListViewItem">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsMaintenance}" Value="True">
            <Setter Property="Background" Value="Gainsboro"  />
            <Setter Property="Foreground" Value="Red" />
        </DataTrigger>
        <Trigger Property="IsSelected" Value="True" >
            <Setter Property="FontWeight" Value="Bold" />
        </Trigger>
    </Style.Triggers>
</Style>

答案 2 :(得分:0)

感谢您的反馈!我接受了BTownTKD关于实现IValueConverter的建议,尽管我的代码有一些改动。我发现我需要定义&#34; local&#34;我的窗口属性在XAML中的范围。

另外,我发现绑定实际上并没有改变文本颜色。在单步执行代码并看到正确调用该方法之后,我将返回的结果硬编码到XAML中以确保它们正常工作(前景=&#34;黑色&#34;或前景=&#34;#FF00000& #34)。我注意到在单步执行返回对象是&#34;颜色&#34;在原始绑定中的对象,并且通过我将颜色硬编码到XAML中,它们实际上是字符串。所以我稍微修改了代码,将.ToString()添加到我返回的对象中,VOILA就可以了!再次感谢您的帮助!

仅供参考,这是更新的代码位:

XAML:

   <Window x:Class="SiteMaintenance.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SiteMaintenance"
        Title="MainWindow" 
        Height="600" 
        Width="1000">
    <Window.Resources>
        <local:MaintenenceColorConverter x:Key="MyColorConverter" NormalColor="Black" NoMaintenanceRequiredColor="Gray" />
    </Window.Resources>

    <Grid Margin="0,0,2,0">

        <ListBox x:Name="allSites_LB" 
                 HorizontalAlignment="Left" 
                 Height="400" 
                 Margin="20,60,0,0" 
                 VerticalAlignment="Top" 
                 Width="945"
                 Loaded="allSites_LB_Loaded" 
                 BorderThickness="1" SelectionChanged="allSites_LB_SelectionChanged"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                 >
            <ListBox.ItemTemplate >
                <DataTemplate >
                    <Border BorderBrush="Black" BorderThickness="0,0,0,1" Margin="-20,1,0,1" Padding="0,5,0,5" >
                        <Grid Margin="75,3" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="400" />
                                <ColumnDefinition Width="345" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="{Binding SiteNo}" Grid.Column="0" FontSize="16" Foreground="{Binding MaintStatus, Converter={StaticResource MyColorConverter}}"  />
                            <TextBlock Text="{Binding Address}" Grid.Column="1" FontSize="16" Margin="50,1" Foreground="{Binding MaintStatus, Converter={StaticResource MyColorConverter}}"  />
                            <TextBlock Text="{Binding MaintStatus}" Grid.Column="2" FontSize="16" Foreground="{Binding MaintStatus, Converter={StaticResource MyColorConverter}}" />
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <Button x:Name="viewHistory_BTN" 
                Content="View History" 
                HorizontalAlignment="Left" 
                Height="52" 
                Margin="20,496,0,0" 
                VerticalAlignment="Top" 
                Width="172" FontSize="20"
                />

        <Button x:Name="startMaintenance_BTN" 
                Content="Start Maintenance"
                HorizontalAlignment="Left" 
                Height="52" 
                Margin="793,496,0,0" 
                VerticalAlignment="Top" 
                Width="172" FontSize="20"
                />
        <TextBox x:Name="Site_Address" 
                 HorizontalAlignment="Left" 
                 Height="21" 
                 Margin="51,39,0,0" 
                 TextWrapping="Wrap" 
                 Text="Site Number" 
                 VerticalAlignment="Top" 
                 Width="75" 
                 BorderBrush="White" 
                 IsReadOnly="True" 
                 IsEnabled="False"

                 />
        <TextBox x:Name="Address_Title" 
                 HorizontalAlignment="Left" 
                 Height="21" 
                 Margin="380,34,0,0" 
                 TextWrapping="Wrap" 
                 Text="Address" 
                 VerticalAlignment="Top" 
                 Width="75" 
                 BorderBrush="White"
                 IsReadOnly="True" 
                 IsEnabled="False"

                 />
        <TextBox x:Name="maint_Title" 
                 HorizontalAlignment="Left" 
                 Height="21" 
                 Margin="699,34,0,0" 
                 TextWrapping="Wrap" 
                 Text="Maintenance Record" 
                 VerticalAlignment="Top" 
                 Width="117" 
                 BorderBrush="White" 
                 IsReadOnly="True" 
                 IsEnabled="False"
                 />

    </Grid>
</Window>

C#代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;



namespace SiteMaintenance
{

public partial class MainWindow : Window
{

    /**
     * CLASS VARIABLES
     * */
    private SqlConnection localdbConnection;        // Connection to Site Maintenance DB (LOCAL)
    private System.Data.DataSet allSitesResults;



    // MAIN THREAD
    public MainWindow()
    {
        InitializeComponent();

        // try to open SQL Connection
        try {
            localdbConnection = new SqlConnection(Properties.Settings.Default.localdb);
            localdbConnection.Open();
        } catch(Exception ex) {
           System.Windows.MessageBox.Show("local SQL connection unable to connect");
           return;
        }

        viewHistory_BTN.IsEnabled = false;
        startMaintenance_BTN.IsEnabled = false;
        startMaintenance_BTN.IsDefault = true;
    }

    /**
     * Load dataset into datagrid 
     * LAZY LOADING
     * */
    private void DataGrid_Loaded(object sender, RoutedEventArgs e)
    {
        // init command object
        SqlCommand myCommand = new SqlCommand();
        myCommand.CommandText = "dbo.usp_GetSites";
        myCommand.CommandType = System.Data.CommandType.StoredProcedure;
        myCommand.Connection = localdbConnection;

        // init data adaptor
        SqlDataAdapter sites = new SqlDataAdapter();
        sites.SelectCommand = myCommand;

        //init DataSet
        allSitesResults = new System.Data.DataSet();

        sites.Fill(allSitesResults, "tblSites");

        int tableCount = allSitesResults.Tables.Count;

        System.Data.DataTable test = allSitesResults.Tables[0];

        int rowCount = test.Rows.Count;

    }


    private void sites_DG_CurrentCellChanged(object sender, EventArgs e)
    {
        String siteName = allSitesResults.Tables[0].Rows[0][1].ToString();

    }

    private void allSites_LB_Loaded(object sender, RoutedEventArgs e)
    {
        // init command object
        SqlCommand myCommand = new SqlCommand();
        myCommand.CommandText = "dbo.usp_GetSitesANDCompletedDate";
        myCommand.CommandType = System.Data.CommandType.StoredProcedure;
        myCommand.Connection = localdbConnection;

        // init data adaptor
        SqlDataAdapter sites = new SqlDataAdapter();
        sites.SelectCommand = myCommand;

        //init DataSet
        allSitesResults = new System.Data.DataSet();

        sites.Fill(allSitesResults, "tblSites");

        allSites_LB.ItemsSource = allSitesResults.Tables["tblSites"].DefaultView;

    }


    // do not allow selection of maintenance records that do not exist
    private void allSites_LB_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

        // grab the index
        int selectedIndex = allSites_LB.SelectedIndex;
        if (selectedIndex == -1) return;                //WITHOUT THIS CHECK, UN-SELECTION WILL CAUSE LOGIC FAILURE

        System.Data.DataRowView tempData = (System.Data.DataRowView)allSites_LB.Items[allSites_LB.SelectedIndex];

        // grab the completed date field
        String completedDate = tempData["CompletedDate"].ToString();
        String siteMaintID = tempData["SiteMaintID"].ToString();

        // remove selected index if completed date and site Maint ID is null
        if (siteMaintID != "" && completedDate == "")
        {
            startMaintenance_BTN.IsEnabled = true;
        }
        else 
        {
            allSites_LB.SelectedIndex = -1;
            startMaintenance_BTN.IsEnabled = false;
        }

    }


    private String maintRequired(object sender, SelectionChangedEventArgs e)
    {
        int selectedIndex = allSites_LB.SelectedIndex;
        if (selectedIndex < 0) return null;

        System.Data.DataRowView tempData = (System.Data.DataRowView)allSites_LB.Items[allSites_LB.SelectedIndex];

        // grab the completed date field
        String completedDate = tempData["CompletedDate"].ToString();
        String siteMaintID = tempData["SiteMaintID"].ToString();

        if (siteMaintID != "" && completedDate == "")
        {
            return "Maintenance Required";
        }
        else
        {
            return "No Maintenance";
        }
    }

}

public class MaintenenceColorConverter : IValueConverter
{

    public Color NormalColor { get; set; }
    public Color NoMaintenanceRequiredColor { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        if (value.ToString() == "No Maintenance Required") return NoMaintenanceRequiredColor.ToString();

        return NormalColor.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

}

}

我稍后会使用BTown的优化来清理我的代码,但至少它正在工作!